Dichiarare un parametro del metodo a blocchi senza usare un typedef


146

È possibile specificare un parametro di blocco metodo in Objective-C senza usare un typedef? Deve essere, come i puntatori a funzioni, ma non posso colpire la sintassi vincente senza usare un typedef intermedio:

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

solo le compilazioni precedenti, tutte falliscono:

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

e non ricordo quali altre combinazioni ho provato.


Risposte:


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

9
+1, anche se a typedefdovrebbe essere preferito per casi più complicati.
Fred Foo,

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

6
Questi sono solo nomi di parametri. Usali e basta.
Macmade,

1
@larsmans Sono d'accordo, a meno che questo particolare predicato / blocco non venga utilizzato in molti luoghi in cui sarebbe più chiaro averlo scritto a macchina. Apple ha definito una serie di blocchi che erano abbastanza semplici, ma lo hanno fatto in modo che fosse facile trovare quello che volevano nella documentazione.
mtmurdock,

2
Raccomandazione forte! Dai un nome alle tue variabili. Si completeranno automaticamente in codice utilizzabile. Quindi sostituire BOOL ( ^ )( int )con BOOL ( ^ )( int count ).
funroll

65

Ecco come va, ad esempio ...

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

C'è un motivo per cui non usi il metodo [NSString isEqualToString:]?
orkoden,

2
Niente di specifico. Sono solo abituato a usare "confronta:" molto. '[NSString isEqualToString:]' è un modo migliore però.
Mohammad Abdurraafay,

Hai bisogno della parola responsenella smartBlocksdefinizione del metodo? Non potresti semplicemente dirlo (NSString*))handler {?
Ash

Potresti avere (NSString *)) handler. Anche questo è valido.
Mohammad Abdurraafay,


9

Un altro esempio (questo problema beneficia di molteplici):

@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

Ancora più chiaro!

[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));
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.