2012-06-11 23 views
6

का उपयोग करके एनएसएआरएआरई में ऑब्जेक्ट इंडेक्स की खोज में मैंने एनएसएआरएआरई इंडेक्सऑफ ऑब्जेक्टपैसिंगटेस्ट का उपयोग करके कुछ उदाहरण देखे हैं, लेकिन मैं उन्हें काम नहीं कर सका (वे एक वैध इंडेक्स नहीं लौटाएंगे)। तो अब मैं एक इनलाइन ब्लॉक का उपयोग करने की कोशिश कर रहा हूं। मैंने इसे एक ब्लॉक टाइप करके किया है, फिर इसे एक संपत्ति के रूप में सेट किया है, इसे संश्लेषित कर रहा है, और इसे कन्स्ट्रक्टर में प्रारंभ कर दिया है। हालांकि इस प्रकार का पूरा बिंदु म्यूट प्रस्तुत करता है, क्योंकि मैं आसानी से एक विधि बना सकता हूं और इसके बजाय इसका उपयोग कर सकता हूं (कम टाइपिंग, कम प्रयास)।एक इनलाइन ब्लॉक

Observations *obs = [self.myAppointment.OBSERVATIONS objectAtIndex: ^NSInteger (NSString *keyword){ 
    for (Observations *obs in self.myAppointment.OBSERVATIONS) { 
     if ([obs.TIME isEqualToString:keyword] == YES) return (NSInteger)[self.myAppointment.OBSERVATIONS indexOfObject:obs]; 
    } 
    return (NSInteger)-1; 
}]; 

हालांकि Xcode बस यह नहीं होगा:

मैं क्या हासिल करने की कोशिश कर रहा हूँ इस के साथ कुछ न कुछ है। मैं विभिन्न रूपों की कोशिश की है, लेकिन घोषणा करके इनलाइन एक समस्या है, जो अजीब है, क्योंकि जैसा कि मैंने कहा है, यह typedefing घोषित, और synthesizing इसे इस तरह से काम करता है लगता है:

Observations *obs = [self.myAppointment.OBSERVATIONS objectAtIndex:findObs(keyword)]; 

findObs कहां है फिर एक परिभाषित ब्लॉक जो एक ही काम करता है। क्या यह एक वाक्यविन्यास मुद्दा है, या क्या मुझे कुछ और महत्वपूर्ण याद आ रही है?

उत्तर

24

-objectAtIndex: पैरामीटर के रूप में NSUInteger लेता है, लेकिन आप इसे एक ब्लॉक पास कर रहे हैं (^ द्वारा दर्शाया गया है)। को -objectAtIndex: पर से गुजरने के बाद, आपका दूसरा उदाहरण findObs (जो आपका ब्लॉक हो सकता है) को कॉल करता है।

आप शायद गठबंधन करने के लिए -objectAtIndex:-indexOfObjectPassingTest: साथ हैं:

NSString *keyword = /* whatever */; 
NSArray *array = self.myAppointment.OBSERVATIONS; 
NSUInteger idx = [array indexOfObjectPassingTest:^(id obj, NSUInteger idx, BOOL *stop){ 
    Observations *obs = (Observations*)obj; 
    return [obs.TIME isEqualToString:keyword]; 
}]; 
if (idx != NSNotFound) 
    Observations *obs = [array objectAtIndex:idx]; 
+0

धन्यवाद कि महान काम किया। इसलिए, मैं इसे एक एनएसआईएनटेगर पैरामीटर के रूप में एक इनलाइन ब्लॉक से गुजर रहा हूं (अनिवार्य रूप से ब्लॉक के रिटर्न वैल्यू को पैरामीटर के रूप में पारित करने की अपेक्षा करता है) ऐसा करने योग्य नहीं है, जब तक कि इसका प्रकार परिभाषित और संश्लेषित न हो? –

+0

आप अपने ब्लॉक इन-लाइन को भी कॉल कर सकते हैं: '[... objectAtIndex: (^ एनएसआईएनटेगर (एनएसएसटींग * के) {...}) (कीवर्ड)]; ', लेकिन चीजें थोड़ा गन्दा दिखने लगती हैं। –

+1

यह उदाहरण सरणी में परीक्षण पास करने वाली अंतिम वस्तु को वापस कर देगा। जैसे ही पहली ऑब्जेक्ट मिलती है पुनरावृत्ति को रोकने के लिए, आपको 'Y stop' – Moose

3

यह typedef या कुछ भी संश्लेषण अपने दूसरे उदाहरण के काम करने के लिए आवश्यक नहीं है - बस एक विधि है, जो इस प्रकार दिखाई देगा से ब्लॉक वापसी:

-(NSUInteger(^)(NSArray *, NSString *))findObs { 
    return ^(NSArray *array, NSString *keyword) { 
     for (NSUInteger i = 0; i < [array count]; i++) { 
      Observations *obs = [array objectAtIndex:i]; 
      if ([obs.TIME isEqualToString:keyword]) { 
       return i; 
      } 
     } 
     return NSNotFound; 
    }; 
} 

Observations *obs = [self.myAppointment.OBSERVATIONS objectAtIndex:[self findObs](keyword)]; 

यहां कुछ good reasons for defining blocks as method return values, rather than inline हैं।

+1

आपको उस ब्लॉक को कॉपी करने की आवश्यकता है, जिसे आप वापस लौट रहे हैं, जब तक आप एआरसी का उपयोग नहीं कर रहे हैं जो आपके लिए – user102008

+1

हां, @ user102008 है, यह सही है। मैं आम तौर पर इन दिनों एआरसी मानता हूं, जब तक कि यह किसी के कोड नमूने से स्पष्ट न हो कि वे एआरसी का उपयोग नहीं कर रहे हैं। –

4

यह एक उदाहरण है जो तारों की सरणी में एक स्ट्रिंग का सूचकांक देता है। इसे किसी भी प्रकार की वस्तु के अनुकूल बनाया जा सकता है।

NSString* myString = @"stringToFind"; 
NSUInteger objectIndex = [myStringArray indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) { 
     return (*stop = ([obj isEqualToString:myString])); 
    }]; 

ठीक मूल सवाल का जवाब करने के लिए:

NSString *keyword = @"myKeyword"; 
NSUInteger index = [self.myAppointment.OBSERVATIONS indexOfObjectPassingTest:^(id obj, NSUInteger idx, BOOL *stop) { 
    return (*stop = [(Observations*)obs.TIME isEqualToString:keyword]); 
}]; 
Observations *obs = (index!=NSNotFound) ? self.myAppointment.OBSERVATIONS[index] : NULL; 

लेकिन यह एक कीवर्ड के साथ कुछ समय कहा जाता है की तुलना करने के काफी अजीब बात है ...;)