2009-07-08 12 views
9

मैं ObjectiveC सीख रहा हूं और आत्मनिरीक्षण से संबंधित एक समस्या में भाग गया। असल में, मैं वस्तुओं की एक सरणी के माध्यम से लूपिंग कर रहा हूं और यह निर्धारित कर रहा हूं कि वे lowercaseString चयनकर्ता स्वीकार करते हैं या नहीं। यदि वे करते हैं, तो मैं ऑब्जेक्ट पर उस चयनकर्ता को कॉल करता हूं। यह सुनिश्चित करने के बाद कि ऑब्जेक्ट उस चयनकर्ता को जवाब देता है, मैं इसे कॉल करता हूं। हालांकि, जब मैं करता हूं, मुझे यह चेतावनी मिलती है: "चेतावनी: 'NSObject;' -lowercaseString 'का जवाब नहीं दे सकता है""एनएसओब्जेक्ट" से छुटकारा पाएं '-omeMethod' 'का जवाब नहीं दे सकता है चेतावनी

हालांकि कोड लिखित के रूप में ठीक काम करता है, लेकिन मुझे चेतावनी नहीं मिलनी चाहिए। मुझे लगता है कि यह सुनिश्चित करने के लिए एक "सही" तरीका है कि मुझे यह चेतावनी नहीं मिलती है (यानी चेतावनियां बंद किए बिना)। कोई विचार?

NSMutableArray *myArray = [[NSMutableArray alloc] init]; 

[myArray addObject:@"Hello!"]; 
[myArray addObject:[NSURL URLWithString:@"http://apple.com"]]; 
[myArray addObject:[NSProcessInfo processInfo]]; 
[myArray addObject:[NSDictionary dictionary]]; 

SEL lowercaseSelector = @selector(lowercaseString); 

for (NSObject *element in myArray) { 
    if ([element respondsToSelector:lowercaseSelector]) { 
     NSLog([element lowercaseString]); // Warning here 
    } 
} 
+0

इसके अलावा, अगर मुझे "चयनकर्ता" शब्दावली गलत हो रही है, तो कृपया मुझे सही करें। :) – Tyson

+3

* एनएसएलओजी को गैर-स्थिर तारों को पास न करें। एक सुरक्षा जोखिम है। आपको लगता है कि आप इस मामले में सुरक्षित हैं, लेकिन इसकी आदत में न आएं। आप अनिवार्य रूप से इसे ऐसे मामले में कर सकते हैं जो एक सुरक्षा छेद खोलता है। – kperryua

+0

क्या आपके पास इस सुरक्षा छेद के बारे में अधिक जानकारी के लिए एक लिंक है? मैं निश्चित रूप से इसके बारे में अधिक पढ़ने में रुचि रखता हूं। – Tyson

उत्तर

15

तुम भी id जो वस्तु के किसी भी प्रकार है उपयोग कर सकते हैं।

for (id element in myArray) { 
    if ([element respondsToSelector:lowercaseSelector]) { 
     NSLog([element lowercaseString]); 
    } 
} 
+0

मुझे लगा कि एनएसओब्जेक्ट उचित होगा, लेकिन, वास्तव में, आईडी इसे करने का एक बेहतर तरीका प्रतीत होता है। – Tyson

+0

जब तक आपको तत्व को बनाए रखने या रिलीज़ करने की आवश्यकता नहीं है ;-) –

+0

किसी आईडी पर retai/release को कॉल करने में क्या गलत है? –

4

बस समारोह कॉल करने से पहले एक NSString करने के लिए अपने NSObject डाली:

for (NSObject *element in myArray) { 
    if ([element respondsToSelector:lowercaseSelector]) { 
     NSLog([(NSString*)element lowercaseString]); // No warning! 
    } 
} 
+0

लेकिन क्या होगा यदि ऑब्जेक्ट उन सभी चयनकर्ताओं का समर्थन नहीं करता जो NSString का समर्थन करता है? मेरी ओओपी-भावना मुझे बताती है कि यह बुरा होगा। मैं बस एक चयनकर्ता की जांच कर रहा हूं, भले ही यह किस सुपरक्लास से संबंधित है। – Tyson

+0

ठीक है, आप मानते हैं कि -लोवरकेसस्ट्रिंग एक एनएसएसटींग लौटाता है, क्योंकि एनएसएलओजी प्रारूप स्ट्रिंग के लिए यही अपेक्षा करता है। यदि, किसी भी कारण से, यह एक एनएसएसटींग वापस नहीं करता है, तो आप प्रारूप स्ट्रिंग के रूप में एनएसएसटींग के अलावा कुछ और पास कर रहे हैं, और एनएसएलओजी इस पर चकित होगा। –

+0

'लोअरकेसस्ट्रिंग' प्राप्त करने का सबसे सुरक्षित तरीका यह है कि इसे एक चर में संग्रहीत करें, और जांच करें कि यह एक प्रकार का एनएसएसटींग है या नहीं। आपको शायद उस भद्दा होने की आवश्यकता नहीं है, हालांकि, और यदि आप नहीं होने वाले हैं, तो आप वैरिएबल को घोषित कर सकते हैं, या वापसी मूल्य को 'एनएसएसटींग *' पर डाल सकते हैं। –

6

performSelector: का उपयोग करने के बारे में कैसे?

SEL lowercaseSelector = @selector(lowercaseString); 

for (NSObject *element in myArray) { 
    if ([element respondsToSelector:lowercaseSelector]) { 
     NSLog([element performSelector:lowercaseSelector]); // No warning 
    } 
} 

यह आपके कंपाइलर चेतावनी से छुटकारा पा जाएगा।

+0

आह, ऐसा करने के लिए यह एक अच्छा तरीका लगता है। जवाब के लिए धन्यवाद। – Tyson

1

आईडी के रूप में कास्टिंग चेतावनी को हटा दिया।

if ([self.content respondsToSelector:@selector(setDelegate:)]) 
{ 
    [(id)self.content setDelegate:nil]; 
} 
संबंधित मुद्दे