Déclarer un paramètre de méthode de bloc sans utiliser de typedef

146

Est-il possible de spécifier un paramètre de bloc de méthode dans Objective-C sans utiliser de typedef? Cela doit être, comme les pointeurs de fonction, mais je ne peux pas trouver la syntaxe gagnante sans utiliser un typedef intermédiaire:

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

seuls les compilations ci-dessus, tous échouent:

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

et je ne me souviens plus des autres combinaisons que j'ai essayées.

Bogatyr
la source

Réponses:

238
- ( void )myMethodTakingPredicate: ( BOOL ( ^ )( int ) )predicate
Macmade
la source
9
+1, bien que a typedefdevrait vraiment être préféré pour les cas plus compliqués.
Fred Foo
3
- ( void )myMethodTakingPredicate: ( BOOL ( ^ )( NSString *name, NSString *age ) )predicate { //How Should I Access name & age here...? }
Mohammad Abdurraafay le
6
Ce ne sont que des noms de paramètres. Utilisez-les simplement.
Macmade le
1
@larsmans Je suis d'accord, à moins que ce prédicat / bloc particulier ne soit utilisé dans de nombreux endroits où il serait plus clair de le faire typer. Apple a défini un certain nombre de blocs qui étaient assez simples, mais ils l'ont fait de telle sorte qu'il était facile de trouver ce qu'ils voulaient dans la documentation.
mtmurdock
2
Forte recommandation! Nommez vos variables. Ils seront automatiquement complétés en code utilisable. Alors remplacez BOOL ( ^ )( int )par BOOL ( ^ )( int count ).
funroll
65

C'est ainsi que ça se passe, par exemple ...

[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
la source
Y a-t-il une raison pour laquelle vous n'utilisez pas la méthode [NSString isEqualToString:]?
orkoden
2
Rien de spécial. Je suis juste habitué à utiliser «comparer:» beaucoup. «[NSString isEqualToString:]» est un meilleur moyen cependant.
Mohammad Abdurraafay
Avez-vous besoin du mot responsedans la smartBlocksdéfinition de la méthode? Ne pourriez-vous pas simplement dire (NSString*))handler {?
Ash
Vous pouvez avoir (NSString *)) handler. C'est également valable.
Mohammad Abdurraafay
9

Autre exemple (ce problème bénéficie de multiples):

@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
la source
2

Encore plus clair!

[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
la source