如何将基于委托的回调系统转换为基于块的?

时间:2013-01-04 11:01:30

标签: objective-c delegates objective-c-blocks

我有一个类,它有一个基于委托的系统,用于发送不同类型的请求。它使用委托在请求完成时告诉对象,如果成功则是错误。

现在,我还必须检查响应采取适当行动的请求类型。

我有包装类,它应该为我提供基于块的接口。

我将一个完成块和一个错误块传递给一个请求方法,该方法应该在内部使用这个基于委托的类。

当响应出现时,应该自动为该请求类型调用适当的处理程序,并且还取决于成功和错误。

我在SO上看到了一个类似的问题,但对我来说有点不清楚,所以请大致了解如何去做,而不是马上把它标记为重复。

2 个答案:

答案 0 :(得分:2)

这是一种方法。使用此RAExpendable类动态构建具有基于块的实现的委托。

让我们说你的代表是:

@protocol XDelegate
-(void) foo:(id)response;
@end

https://github.com/evadne/RAExpendable中的RAExpendable.h,RAExpendable.m添加到您的项目中。动态添加委托方法:

    RAExpendable *expendable = [RAExpendable new];
    [expendable addMethodForSelector:@selector(foo:) types:"v@:@" block:^(id x, SEL sel, id response){
        NSLog(@"response is %@", response);
    }];

并将expendable类设置为您的代理:

    someObject.delegate = expendable;

现在,如果你这样做:

    [expendable performSelector:@selector(foo:) withObject:@"OK"];

你得到字符串response is OK。将NSLog替换为您认为合适的成功/失败实现。从现在开始,当您调用foo:时,会执行该块。

如果你想根据你的用例修改它,请注意这个例子的参数是v@:@,根据运行时的Type Encoding指南意味着:void return,self,SEL,宾语。 selfSEL是每个Objective-C方法上存在的两个隐藏参数,第三个参数是方法的第一个非隐藏参数。块的签名必须与方法的签名匹配。

答案 1 :(得分:2)

使用REKit,您可以动态制作代理,如下所示:

id dynamicDelegate;
dynamicDelegate = [[NSObject alloc] init];
[dynamicDelegate respondsToSelector:@selector(foo:) withKey:nil usingBlock:^(id receiver, id response) {
    NSLog(@"response is %@", response);
}];
someObject.delegate = dynamicDelegate;