从MyMethod调用MyThreadRun方法,就像这个
一样NSArray* args = [NSArray arrayWithObjects:arg1, target, NSStringFromSelector(mySelector), nil];
NSThread* mythread= [[[NSThread alloc] initWithTarget:self selector: @selector(MyThreadRun:) object:args] autorelease];
[MyThreadRun start];
在MyThreadRun的最后,我尝试在调用MyMethod的类中调用一个函数来启动线程,如下所示:
NSObject* callbackTarget = [args objectAtIndex:1];
NSString* selector = [args objectAtIndex:2];
[callbackTarget performSelector:NSSelectorFromString(selector) withObject:calculationResult afterDelay:0];
我在选择器指向的方法上有一个断点,它永远不会被击中。
如果我对方法名称进行硬编码,就像这样
[callbackTarget updateWithResult:calculationResult]
它工作正常。
关于performSelector,我需要了解什么?
答案 0 :(得分:23)
调用performSelector:withObject:afterDelay:
的上下文是罪魁祸首。这是正在发生的事情。
performSelector
...系列的某些成员,就像这个一样,不会马上执行选择器;它们在当前运行循环上排队调用,以便在fn返回之后发生,即运行循环的下一个循环。根据apple的说法:“指定延迟为0并不一定会导致选择器立即执行。选择器仍然在线程的运行循环中排队并尽快执行。”
通常这很好并且预期。但是你的代码在你手动启动的线程上调用它...而且这样的线程不会像主线程那样重复运行循环。他们调用在创建时指定的选择器,然后退出。所以:你的代码排队调用你的回调选择器,然后线程退出;并且它的运行循环被抛弃而没有运行...所以你的排队调用永远不会发生。
您可能需要的是performSelectorOnMainThread:withObject:waitUntilDone:
,因为您可能希望回调发生在首先调用MyMethod
方法的线程上,这可能是主线程。
更一般地说,线程是非常棘手的东西。我强烈建议您查看NSOperationQueue
,NSBlockOperation
和相关技巧 - 它们可以消除大量的痛苦。
答案 1 :(得分:4)
时
NSString* selector = [args objectAtIndex:2];
等于 updateWithResult 或 updateWithResult:?
他们是两种不同的方法。你想要一个带冒号的那个。
答案 2 :(得分:2)
删除“afterDelay:0”并且您的代码有效。另外“[MyThreadRun start]”应为“[mythread start]”。