我有一个objective-c类,我只想从主线程中调用它。
我可以通过向每个选择器添加类似的东西来实现这一点:
- (void) exampleSelector: (id) param {
if (![NSThread isMainThread]) {
[self peformSelectorOnMainThread:@selector(exampleSelector:) withObject:param waitUntilDone:YES];
return;
}
// Do stuff it's not safe to do outside the main thread
}
然而,将此添加到每个选择器似乎有点痛苦。有没有什么方法可以自动拦截对这个类的对象的所有调用,检查它所在的线程,如果它不是主线程,则使用performSelectorOnMainThread?
答案 0 :(得分:1)
嗯。我不确定是否可以这样做;我想不出办法这样做。我倾向于做的是用代理替换对象。代理将负责在正确的线程中将调用转发给对象。
@interface Forwarder : NSObject
{
id recipient;
}
- (Forwarder *)initWithRecipient:(id)inRecipient;
@end
@implementation Forwarder
- (Forwarder *)initWithRecipient:(id)inRecipient {
[inRecipient retain];
recipient = inRecipient;
return self;
}
- (void)dealloc {
[recipient release];
[super dealloc];
}
- (void)forwardInvocation:(NSInvocation *)anInvocation {
if ([recipient respondsToSelector: [anInvocation selector]]) {
if (![NSThread isMainThread]) {
// Note: only works with methods that take one argument. Should add
// error handling for other methods
id argument;
[invocation getArgument: &argument atIndex: 2];
[recipient performSelectorOnMainThread: [anInvocation selector] withObject: argument waitUntilDone: YES];
} else {
[anInvocation invokeWithTarget:recipient];
}
} else {
[super forwardInvocation:anInvocation];
}
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
if ([recipient respondsToSelector: aSelector])
return [recipient methodSignatureForSelector: aSelector];
else
return [super methodSignatureForSelector: aSelector];
}
@end
答案 1 :(得分:0)
也许您应该对方法的调用者施加限制,不要从任意线程调用它。如果主线程被阻塞等待来自线程B的结果,并且线程B调用类似于示例中的方法,则会出现死锁。