Declare a block method parameter without using a typedef
90,217
Solution 1
- ( void )myMethodTakingPredicate: ( BOOL ( ^ )( int ) )predicate
Solution 2
This is how it goes, for example...
[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");
}
}
Solution 3
As a method parameter:
- (void)someMethodThatTakesABlock:(returnType (^)(parameterTypes))blockName;
Solution 4
Another example (this issue benefits from multiple):
@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
}];
Solution 5
Even more clear !
[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));
}
Related videos on Youtube
Author by
Bogatyr
Updated on January 27, 2020Comments
-
Bogatyr about 4 years
Is it possible to specify a method block parameter in Objective-C without using a typedef? It must be, like function pointers, but I can't hit on the winning syntax without using an intermediate typedef:
typedef BOOL (^PredicateBlock_t)(int); - (void) myMethodTakingPredicate:(PredicateBlock_t)predicate
only the above compiles, all these fail:
- (void) myMethodTakingPredicate:( BOOL(^block)(int) ) predicate - (void) myMethodTakingPredicate:BOOL (^predicate)(int)
and I can't remember what other combinations I've tried.
-
Kyle Clegg almost 10 years
-
-
Fred Foo about 13 years+1, though a
typedef
should really be preferred for more complicated cases. -
Mohammad Abdurraafay over 12 years
- ( void )myMethodTakingPredicate: ( BOOL ( ^ )( NSString *name, NSString *age ) )predicate { //How Should I Access name & age here...? }
-
Macmade over 12 yearsThose are just parameter names. Just use them.
-
mtmurdock about 12 years@larsmans I agree, unless this particular predicate/block is used in a lot of places where it would be more clear to have it typedef'd. Apple has defined a number of blocks that were quite simple, but did so such that it was easy to find what they wanted in documentation.
-
user4951 over 11 yearsand how to pass a block to that function.
-
orkoden about 11 yearsIs there a reason you don't use the [NSString isEqualToString:] method?
-
Mohammad Abdurraafay about 11 yearsNothing specific. I'm just use to use 'compare:' a lot. '[NSString isEqualToString:]' is a better way though.
-
devios1 about 10 yearsUgh. There is nothing intuitive about this syntax at all. :(
-
Macmade about 10 years@chaiguy It is if you know how to deal with function pointers. It's the same syntax, with ^ instead of *
-
devios1 about 10 years@Macmade That's the syntax I'm complaining about. Not criticizing your answer mind you; already +1'd.
-
funroll over 9 yearsStrong recommendation! Name your variables. They will autocomplete into usable code. So replace
BOOL ( ^ )( int )
withBOOL ( ^ )( int count )
. -
Ash over 7 yearsDo you need the word
response
in thesmartBlocks
method definition? Couldn't you just say(NSString*))handler {
? -
Mohammad Abdurraafay over 7 yearsYou may have
(NSString *)) handler
. That's valid as well.