Zadeklaruj parametr metody bloku bez użycia typu typedef


146

Czy można określić parametr bloku metody w Objective-C bez użycia typedef? Musi być, podobnie jak wskaźniki do funkcji, ale nie mogę trafić w składnię wygrywającą bez użycia pośredniej czcionki:

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

kompiluje się tylko powyższe, wszystkie te zawodzą:

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

i nie pamiętam, jakich innych kombinacji próbowałem.


Odpowiedzi:


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

9
+1, chociaż typedefnaprawdę powinno być preferowane w bardziej skomplikowanych przypadkach.
Fred Foo

3
- ( void )myMethodTakingPredicate: ( BOOL ( ^ )( NSString *name, NSString *age ) )predicate { //How Should I Access name & age here...? }
Mohammad Abdurraafay

6
To tylko nazwy parametrów. Po prostu ich używaj.
Macmade

1
@larsmans Zgadzam się, chyba że ten konkretny predykat / blok jest używany w wielu miejscach, w których byłoby bardziej oczywiste, aby je zdefiniować. Firma Apple zdefiniowała szereg bloków, które były dość proste, ale zrobiło to tak, że łatwo było znaleźć to, czego chcieli w dokumentacji.
mtmurdock

2
Mocna rekomendacja! Nazwij swoje zmienne. Będą automatycznie uzupełniane do użytecznego kodu. Więc zastąpić BOOL ( ^ )( int )z BOOL ( ^ )( int count ).
funroll

65

Tak to jest, na przykład ...

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

Czy jest jakiś powód, dla którego nie używasz metody [NSString isEqualToString:]?
orkoden

2
Nic konkretnego. Po prostu używam często „porównaj”. Jednak „[NSString isEqualToString:]” jest lepszym sposobem.
Mohammad Abdurraafay

Czy potrzebujesz słowa responsew smartBlocksdefinicji metody? Nie mógłbyś po prostu powiedzieć (NSString*))handler {?
Ash

Możesz mieć (NSString *)) handler. To też jest ważne.
Mohammad Abdurraafay,


9

Inny przykład (ten problem korzysta z wielu):

@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

Jeszcze wyraźniej!

[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));
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.