spender
spender

Reputation: 120450

Can blocks/methods be interchangeable?

I'm coming from C#/Java/JS to objectiveC and I'm only a couple of days in, so go easy on me.

...so I have a method that takes a block as a parameter:

-(void)subToPub: (NSString*)publisherName 
      channelId: (NSString*)channelId 
       callback: (void(^)(NSDictionary*))cb

which I would usually use as follows:

[myObj  subToPub:@"someId" 
       channelId:@"someOtherId" 
        callback:[(^(NSDictionary* msg){
                    NSLog(@"cb2: %@",msg);
                 }) copy]
];

Now, say I have another method with a compatible signature, for instance:

-(void)subscribeHandler:(NSDictionary*)msg{
    NSLog(@"cb2: %@",msg);
}

is it possible to pass this in as the callback to the subToPub method above, or do I need to wrap this method call in a block?

Upvotes: 2

Views: 114

Answers (3)

Tommy
Tommy

Reputation: 100632

Logically you need three pieces of information to make a call to the selector described. The object instance, the name of the selector and the dictionary parameter.

The block you pass accepts only one piece of information when called — the dictionary. Everything else needs to be captured within the block.

So, logically, the selector can't be a straight substitution for the block. Besides anything else, where does knowledge of which instance to call it on come from?

The only way to produce a record of 'this method on this specific object' and compact that into a single object is to put it into a block.

If you have a defined format of method you want to call (in this case, one with a single argument) and know the object implicitly then you might consider passing in a selector (SEL). So e.g.

[myObj  subToPub:@"someId" 
       channelId:@"someOtherId" 
        callback:@selector(subscribeHandler:)
];

... and subsequently, assuming you know the object you want to talk to as obj and have stored the SEL you received as selector:

[obj performSelector:selector withObject:msg];

If you want to pass more than one argument then you need to start fooling about with NSInvocations; it's quite ugly and you'll soon start to appreciate why closures were added to the language.

Upvotes: 6

Bryan Chen
Bryan Chen

Reputation: 46598

you can do this

[myObj  subToPub:@"someId" 
       channelId:@"someOtherId" 
        callback:[(^(NSDictionary* msg){
                    [object subscribeHandler:msg];
                 }) copy]
];

Upvotes: 2

Rob
Rob

Reputation: 11733

You need to wrap it. Clearly you know how to do that, e.g. ^(void)subscribeHandler:@[@"key": @"value"].

Upvotes: 1

Related Questions