PerformSelector不工作

时间:2011-08-28 05:03:56

标签: objective-c ios multithreading

从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,我需要了解什么?

3 个答案:

答案 0 :(得分:23)

调用performSelector:withObject:afterDelay:的上下文是罪魁祸首。这是正在发生的事情。

performSelector ...系列的某些成员,就像这个一样,不会马上执行选择器;它们在当前运行循环上排队调用,以便在fn返回之后发生,即运行循环的下一个循环。根据apple的说法:“指定延迟为0并不一定会导致选择器立即执行。选择器仍然在线程的运行循环中排队并尽快执行。”

通常这很好并且预期。但是你的代码在你手动启动的线程上调用它...而且这样的线程不会像主线程那样重复运行循环。他们调用在创建时指定的选择器,然后退出。所以:你的代码排队调用你的回调选择器,然后线程退出;并且它的运行循环被抛弃而没有运行...所以你的排队调用永远不会发生。

您可能需要的是performSelectorOnMainThread:withObject:waitUntilDone:,因为您可能希望回调发生在首先调用MyMethod方法的线程上,这可能是主线程。

更一般地说,线程是非常棘手的东西。我强烈建议您查看NSOperationQueueNSBlockOperation和相关技巧 - 它们可以消除大量的痛苦。

答案 1 :(得分:4)

NSString* selector = [args objectAtIndex:2];

等于 updateWithResult updateWithResult:

他们是两种不同的方法。你想要一个带冒号的那个。

答案 2 :(得分:2)

删除“afterDelay:0”并且您的代码有效。另外“[MyThreadRun start]”应为“[mythread start]”。