我有一个包含一些Web服务功能的NSOperation。 NSOperation有一个委托,当操作结束时将被发送消息。
由于NSOperation生活在一个不同的主题上,我必须像这样打电话:
[delegate performSelectorOnMainThread:@selector(getDealersIDSuccess:) withObject:result waitUntilDone:YES];
它工作正常,但它给了我一个警告:
警告: '-performSelectorOnMainThread:withObject:waitUntilDone:' 在协议中找不到
我完全同意这个编译器,它看到一个委托,它检查协议,它没有找到performSelector方法的声明。
我的问题是:我可以通过以不同方式拨打此电话来删除警告吗?
我的两个猜测是我可以(1)编写一个名为
的方法- (void) callDelegateMethodOnMainThred {
[delegate getDealersIDSuccess:result]
}
并通过performSelectorOnMainThread调用它,但是我觉得这个解决方案很麻烦,而且是一个额外的,难以阅读的,在代表团之上的步骤。
第二个解决方案可能是将委托转换为选择器内部父对象的类型,但这只是简单的疯狂而且违背了委托封装模式。
我真的很感激能够更好地理解语言的第三个解决方案:)
提前谢谢。
编辑:添加了委托声明:
id <ISDealersIDDelegate> delegate;
我将我的委托声明为id。委托它自己扩展UIViewController。
我可以看到声明NSObject会起作用。
答案 0 :(得分:18)
performSelectorOnMainThread:withObject:waitUntilDone:
方法在NSObject
类中声明。如果您的委托对象继承自NSObject,则可以将其声明为
NSObject<MyDelegateProtocol> *delegate;
因此,编译器将知道委托响应NSObject的方法,并且不会发出警告。
答案 1 :(得分:3)
在委托或其他协议实现上调用performSelectorOnMainThread可能是更好的解决方案。 让代理人/接收者负责确定是否需要在主线程上做事。
[delegate performSelector:@selector(delegateAction:)
withObject:actionData];
代表实施
- (void)delegateAction:(NSData*)actionData
{
[self performSelectorOnMainThread:@selector(updateUIForAction:)
withObject:actionData
waitUntilDone:NO];
}
- (void)updateUIForAction:(NSData*)actionData
{
// Update your UI objects here
}
它可能看起来像更多的代码,但现在责任在正确的地方
答案 2 :(得分:2)
实际上在iOS 4上我更喜欢使用NSNotifications和Observers(带有Blocks)来对主线程执行更新。
- (id)addObserverForName:(NSString *)name object:(id)obj queue:(NSOperationQueue *)queue usingBlock:(void (^)(NSNotification *))block
我写下了我的设计here。
答案 3 :(得分:2)
1)声明你的委托协议以扩展.h文件中的NSObject协议
@protocol YourDelegateProtocol <NSObject>
2)在你的电话中投射到NSObject
[(NSObject*)delegate performSelectorOnMainThread:@selector(getDealersIDSuccess:) withObject:result waitUntilDone:YES];
我绝对推荐数字(1)。