2010-10-22 8 views
7

मैं उद्देश्य-सी ब्लॉक का उपयोग कर एक बाइनरी खोज को लागू करने की कोशिश कर रहा हूं। मैं फंक्शन indexOfObject:inSortedRange:options:usingComparator: का उपयोग कर रहा हूं। यहाँ एक उदाहरण है।उद्देश्य-सी ब्लॉक इनलाइन कैसे लिखें?

// A pile of data. 
NSUInteger amount = 900000; 
// A number to search for. 
NSNumber* number = [NSNumber numberWithInt:724242]; 

// Create some array. 
NSMutableArray* array = [NSMutableArray arrayWithCapacity:amount]; 
for (NSUInteger i = 0; i < amount; ++i) {; 
    [array addObject:[NSNumber numberWithUnsignedInteger:i]]; 
} 
NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate]; 

// Run binary search. 
int index1 = [array indexOfObject:number 
        inSortedRange:NSMakeRange(0, [array count]) 
          options:NSBinarySearchingFirstEqual 
        usingComparator:^(id lhs, id rhs) { 
         if ([lhs intValue] < [rhs intValue]) { 
          return (NSComparisonResult)NSOrderedAscending; 
         } else if([lhs intValue] > [rhs intValue]) { 
          return (NSComparisonResult)NSOrderedDescending; 
         } 
         return (NSComparisonResult)NSOrderedSame; 
        }]; 
NSTimeInterval stop1 = [NSDate timeIntervalSinceReferenceDate]; 
NSLog(@"Binary: Found index position: %d in %f seconds.", index1, stop1 - start); 

// Run normal search. 
int index2 = [array indexOfObject:number]; 
NSTimeInterval stop2 = [NSDate timeIntervalSinceReferenceDate]; 
NSLog(@"Normal: Found index position: %d in %f seconds.", index2, stop2 - start); 

मुझे आश्चर्य है कि मैं उपर्युक्त कार्य के साथ बाहरी रूप से परिभाषित उद्देश्य-सी ब्लॉक का उपयोग कैसे कर सकता हूं। यहां दो तुलनात्मक कार्य हैं।

NSComparisonResult compareNSNumber(id lhs, id rhs) { 
    return [lhs intValue] < [rhs intValue] ? NSOrderedAscending : [lhs intValue] > [rhs intValue] ? NSOrderedDescending : NSOrderedSame; 
} 
NSComparisonResult compareInt(int lhs, int rhs) { 
    return lhs < rhs ? NSOrderedAscending : lhs > rhs ? NSOrderedDescending : NSOrderedSame; 
} 

उन निम्नलिखित घोषणाओं NSObjCRuntime.h में पाया जा सकता है के संदर्भ में लिखे गए हैं।

enum _NSComparisonResult {NSOrderedAscending = -1, NSOrderedSame, NSOrderedDescending}; 
typedef NSInteger NSComparisonResult; 
typedef NSComparisonResult (^NSComparator)(id obj1, id obj2); 

उत्तर

21

आप कार्यों के समान प्रभाव प्राप्त करने के लिए एक वैश्विक चर के रूप में एक ब्लॉक को परिभाषित कर सकते हैं।

NSComparisonResult (^globalBlock)(id,id) = ^(id lhs, id rhs) { 
    if([lhs intValue] < [rhs intValue]) { 
     return (NSComparisonResult)NSOrderedAscending; 
    } else if([lhs intValue] > [rhs intValue]) { 
     return (NSComparisonResult)NSOrderedDescending; 
    } 
    return (NSComparisonResult)NSOrderedSame; 
}; 

फिर, विधि में तुलना कर:

int index1 = [array indexOfObject:number 
        inSortedRange:NSMakeRange(0, [array count]) 
          options:NSBinarySearchingFirstEqual 
        usingComparator:globalBlock]; 

बाहरी उपयोग के लिए एक शीर्ष लेख में ब्लॉक में कहें,:

NSComparisonResult (^globalBlock)(id,id); 
+0

क्या आप कृपया अपने उत्तर में हेडर घोषणा जोड़ सकते हैं? – JJD

+0

कृपया दौर ब्रेस की स्थिति को सही करें। यह इस 'एनएससीओम्परिसन रीसेट (^ मेक कॉम्पर्सिसब्लॉक) (आईडी, आईडी) = (^ (आईडी एलएचएस, आईडी आरएएस) {...}) जैसा होना चाहिए; '। तो मुझे एक चरित्र को संपादित करने की अनुमति नहीं है। – JJD

+0

@ जेजेडी वास्तव में, उन कोष्ठक अनावश्यक हैं। इनलाइनों से इनलाइन में परिवर्तित होने पर मैंने गलती से उन्हें छोड़ दिया, और पुराने कंपाइलर्स इसे जाने देते हैं। मैं उन्हें हटा दूंगा। – ughoavgfhw

2

मैं जानता हूँ कि यह पुराना है, लेकिन मैं सिर्फ यह भर में भाग गया और मैं अपने ब्लॉक कम महत्वपूर्ण चीज़ों पर काम करने की कोशिश कर रहा है तो यहां आता है ...

मैं एक विधि है कि आपके NSComparator रिटर्न बनाया एक ब्लॉक के रूप में। यह इस तरह दिखता है: मैं ब्लॉक परिभाषा के भीतर के साथ मूल कार्यान्वयन के समान उत्पादन मिला

// Run binary search. 
int index1 = [array indexOfObject:number 
        inSortedRange:NSMakeRange(0, [array count]) 
          options:NSBinarySearchingFirstEqual 
        usingComparator:[self compareNSNumber]]; 
NSTimeInterval stop1 = [NSDate timeIntervalSinceReferenceDate]; 
NSLog(@"Binary: Found index position: %d in %f seconds.", index1, stop1 - start); 

:

-(NSComparisonResult (^) (id lhs, id rhs))compareNSNumber{ 

return [[^(id lhs, id rhs) 
     { 
      return [lhs intValue] < [rhs intValue] ? (NSComparisonResult)NSOrderedAscending : [lhs intValue] > [rhs intValue] ? (NSComparisonResult)NSOrderedDescending : (NSComparisonResult)NSOrderedSame; 

     } copy ] autorelease]; 
} 

मैं तो करने के लिए द्विआधारी खोज निष्पादन बदलकर अपने नमूना कोड को चलाने के लिए सक्षम था विधि कॉल

+0

मैं वास्तव में अपने कार्यान्वयन की तरह। हालांकि, चूंकि मैं 2 सही उत्तरों नहीं दे सकता हूं, इसलिए मुझे @ उगोवागफ्वा पर निर्णय लेना है क्योंकि मैंने बाहरी परिभाषित उद्देश्य-सी ब्लॉक के लिए कहा था। कोई चिंता नहीं! - दिलचस्प बात यह है कि एक्सकोड एक कॉलन और गलती पर एक तर्क जोड़ता है जब मैं स्वत: पूर्ण करता हूं [स्वयं तुलनाएन संख्या: आईडी lhs] '। – JJD

संबंधित मुद्दे