Deklarasikan parameter metode blok tanpa menggunakan typedef

146

Apakah mungkin untuk menentukan parameter blok metode di Objective-C tanpa menggunakan typedef? Itu harus, seperti pointer fungsi, tapi saya tidak bisa menemukan sintaks yang menang tanpa menggunakan typedef perantara:

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

hanya kompilasi di atas, semua ini gagal:

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

dan saya tidak dapat mengingat kombinasi apa yang telah saya coba.

Bogatyr
sumber

Jawaban:

238
- ( void )myMethodTakingPredicate: ( BOOL ( ^ )( int ) )predicate
Dibuat
sumber
9
+1, meskipun typedefharus benar-benar disukai untuk kasus yang lebih rumit.
Fred Foo
3
- ( void )myMethodTakingPredicate: ( BOOL ( ^ )( NSString *name, NSString *age ) )predicate { //How Should I Access name & age here...? }
Mohammad Abdurraafay
6
Itu hanya nama parameter. Gunakan saja.
Macmade
1
@ Larsmans Saya setuju, kecuali predikat / blok khusus ini digunakan di banyak tempat di mana akan lebih jelas untuk mengetiknya. Apple telah menetapkan sejumlah blok yang cukup sederhana, tetapi melakukannya sedemikian rupa sehingga mudah untuk menemukan apa yang mereka inginkan dalam dokumentasi.
mtmurdock
2
Rekomendasi kuat! Namai variabel Anda. Mereka akan melengkapi secara otomatis ke dalam kode yang dapat digunakan. Jadi gantikan BOOL ( ^ )( int )dengan BOOL ( ^ )( int count ).
funroll
65

Begini caranya, misalnya ...

[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");
    }
}
Mohammad Abdurraafay
sumber
Apakah ada alasan Anda tidak menggunakan metode [NSString isEqualToString:]?
orkoden
2
Tidak ada yang khusus. Saya hanya sering menggunakan 'bandingkan:'. '[NSString isEqualToString:]' adalah cara yang lebih baik.
Mohammad Abdurraafay
Apakah Anda memerlukan kata responsedalam smartBlocksdefinisi metode? Tidak bisakah Anda mengatakannya saja (NSString*))handler {?
Ash
Anda mungkin punya (NSString *)) handler. Itu juga valid.
Mohammad Abdurraafay
9

Contoh lain (masalah ini mendapat manfaat dari banyak):

@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
}];
bshirley
sumber
2

Lebih jelas lagi!

[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));
}
Hemang
sumber