2

我是从 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 方法,或者我是否需要将此方法调用包装在一个块中?

4

3 回答 3

6

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

你传递的块在被调用时只接受一条信息——字典。其他所有内容都需要在块内捕获。

因此,从逻辑上讲,选择器不能直接替换块。除此之外,调用哪个实例的知识从何而来?

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

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

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

...随后,假设您知道要与之交谈的对象并将您收到的对象obj存储为:SELselector

[obj performSelector:selector withObject:msg];

如果你想传递多个参数,那么你需要开始使用NSInvocations;它非常难看,您很快就会开始理解为什么将闭包添加到语言中。

于 2013-01-25T01:14:42.940 回答
2

你可以这样做

[myObj  subToPub:@"someId" 
       channelId:@"someOtherId" 
        callback:[(^(NSDictionary* msg){
                    [object subscribeHandler:msg];
                 }) copy]
];
于 2013-01-25T00:40:43.903 回答
1

你需要把它包起来。显然你知道怎么做,例如^(void)subscribeHandler:@[@"key":@"value"]。

于 2013-01-25T00:40:01.173 回答