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.


Jawaban:


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

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");
    }
}

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
}];

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));
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.