我正在为可可应用程序编写中间件,并且正在讨论如何为许多长时间运行的进程设计回调。可可回调设计:最佳实践
当UI将调用其执行很长一段时间的函数,它需要提供一个委托,以允许至少:
- 成功(有返回值)失败的
- 报告的报告(错误值)
- 进展的报告(已完成,预计总)
我已经在过去尝试了一些技巧,下面
所示@interface MyClass {
}
//Callback Option1, delgate conforming to protocol
-(void) longRunningProcess2:(id<CallbackProtocol>) delegate;
//Callback Option2, provide a delegate and allow it to provide selectors to callback
-(void) longRunningProcess3:(id) delegate success:(SEL) s1 failure:(SEL) s2 progress:(SEL) s3
@end
对于选项1,问题是如何短语委托响应。我认为第一种方式是(函数名称是最小的为简单起见)
//have a generic callback protocol for every function
@protocol CallbackProtocolGeneric
-(void) success:(id) returnValue;
-(void) failure:(NSError*) error;
@optional
-(void) progress:(NSInteger) completed of:(NSInteger) total;
@end
//have a separate protocol for every function
@protocol CallbackProtocolWithObjectAForOperation1
-(void) objectA:(ObjectA*) objectA operation1SucceedWithValue:(ReturnObject*) value;
-(void) objectA:(ObjectA*) objectA operation1FailedWithError:(NSError*) error;
@optional
-(void) objectA:(ObjectA*) objectA operation1didProgress:(NSInteger) completed of:(NSInteger) total;
@end
以我的经验, 回调选项1使用通用协议很难因为使用如果一个类想成为一个回调多个操作时,它无法区分它正在接收哪个回调。
回调选项2使用起来很麻烦,感觉不太自然。另外如果协议被扩展,则需要修改每个呼叫。
使用特定协议对于每个过程回拨选项1似乎是最可读的和可扩展的方法,但是不知做一个新的协议为每一个功能是太冗长(说一个给定的对象具有10+这种“长期操作”,然后是10种不同的协议)。
有其他人来执行这样的设计时,什么样的结论?
--edit: 在答复戴夫德隆的回答
我有一个具有“长作业”,每个类或类之间的操作的不真正涉及三类。一些是网络资源请求,另一些则是长时间处理请求。
- 编辑: 一个方面,我似乎有一个问题,我不能调用具有多个参数的消息的运行循环选择器。这是一个设计限制还是有解决方法?
例如,我有一条消息,如 - (ID)someMessage:(ID)值1 otherData:(ID)数值2 MOREDATA:(ID)VALUE3
哪个队列runLoop的不支持这种选择的performSelector功能。
我同意明确指定回调,尽管冗长,会导致更好的可读性。我还没有读入'块',但他们看起来比选择器更加灵活。我总是觉得重载一个参数/两个参数执行选择器功能,其中一个黑客和一个糟糕的设计结果。 – Akusete 2010-07-03 07:56:17