块/方法可以互换吗?

时间:2013-01-25 00:36:42

标签: ios objective-c objective-c-blocks

我来自C#/ Java / JS到objectiveC,我只有几天了,所以对我很轻松。

...所以我有一个方法将块作为参数:

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

我通常会使用如下:

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

现在,假设我有另一种兼容签名的方法,例如:

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

是否可以将此作为回调传递给上面的subToPub方法,或者我是否需要在块中包装此方法调用?

3 个答案:

答案 0 :(得分:6)

逻辑上,您需要三条信息来调用所描述的选择器。对象实例,选择器的名称和字典参数。

您传递的块在调用时只接受一条信息 - 字典。其他所有东西都需要在街区内捕获。

因此,从逻辑上讲,选择器不能直接替换块。除了其他任何事情,知道哪个实例调用它来源于哪里?

在这个特定对象上生成“此方法”记录并将其压缩为单个对象的唯一方法是将其放入块中。

如果你想要调用一个已定义的方法格式(在这种情况下,一个带有一个参数的方法)并且隐式地知道该对象,那么你可以考虑传入一个选择器(SEL)。例如,

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

...然后,假设您知道要与obj对话的对象,并将您收到的SEL存储为selector

[obj performSelector:selector withObject:msg];

如果你想传递多个参数,那么你需要开始愚弄NSInvocation s;它非常难看,你很快就会开始意识到为什么会在语言中添加闭包。

答案 1 :(得分:2)

你可以这样做

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

答案 2 :(得分:1)

你需要包装它。显然你知道如何做到这一点,例如^(void)subscribeHandler:@ [@“key”:@“value”]。