एक टाइपराइफ का उपयोग किए बिना ब्लॉक विधि पैरामीटर घोषित करें


146

क्या टाइप-सी का उपयोग किए बिना ऑब्जेक्ट-सी में एक विधि ब्लॉक पैरामीटर निर्दिष्ट करना संभव है? यह फंक्शन पॉइंटर्स की तरह होना चाहिए, लेकिन मैं बिना इंटरमीडिएट टाइप किएडिफ का उपयोग किए बिना जीतने वाले सिंटैक्स पर हिट नहीं कर सकता:

typedef BOOL (^PredicateBlock_t)(int);
- (void) myMethodTakingPredicate:(PredicateBlock_t)predicate

केवल उपरोक्त संकलन, ये सभी विफल:

-  (void) myMethodTakingPredicate:( BOOL(^block)(int) ) predicate
-  (void) myMethodTakingPredicate:BOOL (^predicate)(int)

और मुझे याद नहीं है कि मैंने और क्या संयोजन किए हैं।


जवाबों:


238
- ( void )myMethodTakingPredicate: ( BOOL ( ^ )( int ) )predicate

9
+1, हालाँकि typedefअधिक जटिल मामलों के लिए वास्तव में पसंद किया जाना चाहिए।
फ्रेड फू

3
- ( void )myMethodTakingPredicate: ( BOOL ( ^ )( NSString *name, NSString *age ) )predicate { //How Should I Access name & age here...? }
मोहम्मद अब्दुर्रफय

6
वे सिर्फ पैरामीटर नाम हैं। बस उनका उपयोग करें।
मैकमेड सेप

1
@ लार्समैन मैं सहमत हूं, जब तक कि यह विशेष रूप से विधेय / ब्लॉक का उपयोग बहुत से स्थानों पर नहीं किया जाता है जहां यह टाइप किए गए समय के लिए अधिक स्पष्ट होगा। ऐप्पल ने कई ब्लॉकों को परिभाषित किया है जो काफी सरल थे, लेकिन उन्होंने ऐसा किया कि यह खोजने में आसान था कि वे प्रलेखन में क्या चाहते हैं।
mtmurdock

2
मजबूत सिफारिश! अपने चरों का नाम बताइए। वे प्रयोग करने योग्य कोड में स्वत: पूर्ण होंगे। इसलिए BOOL ( ^ )( int )साथ बदलें BOOL ( ^ )( int count )
फफूंद

65

उदाहरण के लिए, यह कैसा है ...

[self smartBlocks:@"Pen" youSmart:^(NSString *response) {
        NSLog(@"Response:%@", response);
    }];


- (void)smartBlocks:(NSString *)yo youSmart:(void (^) (NSString *response))handler {
    if ([yo compare:@"Pen"] == NSOrderedSame) {
        handler(@"Ink");
    }
    if ([yo compare:@"Pencil"] == NSOrderedSame) {
        handler(@"led");
    }
}

क्या कोई कारण है जो आप [NSString isEqualToString:] विधि का उपयोग नहीं करते हैं?
orkoden

2
कुछ भी विशिष्ट नहीं। मैं सिर्फ 'तुलना:' का उपयोग करने के लिए उपयोग कर रहा हूं। '[NSString isEqualToString:]' हालांकि एक बेहतर तरीका है।
मोहम्मद अब्दुर्रफय

क्या आपको विधि परिभाषा responseमें शब्द की आवश्यकता है smartBlocks? क्या आप अभी नहीं कह सकते (NSString*))handler {?
ऐश

आपके पास हो सकता है (NSString *)) handler। यही मान्य है।
मोहम्मद अब्दुर्रैफ


9

एक और उदाहरण (यह समस्या कई से लाभ देती है):

@implementation CallbackAsyncClass {
void (^_loginCallback) (NSDictionary *response);
}
// …


- (void)loginWithCallback:(void (^) (NSDictionary *response))handler {
    // Do something async / call URL
    _loginCallback = Block_copy(handler);
    // response will come to the following method (how is left to the reader) …
}

- (void)parseLoginResponse {
    // Receive and parse response, then make callback

   _loginCallback(response);
   Block_release(_loginCallback);
   _loginCallback = nil;
}


// this is how we make the call:
[instanceOfCallbackAsyncClass loginWithCallback:^(NSDictionary *response) {
   // respond to result
}];

2

और भी स्पष्ट!

[self sumOfX:5 withY:6 willGiveYou:^(NSInteger sum) {
    NSLog(@"Sum would be %d", sum);
}];

- (void) sumOfX:(NSInteger)x withY:(NSInteger)y willGiveYou:(void (^) (NSInteger sum)) handler {
    handler((x + y));
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.