PerformSelector not working
MyThreadRun method is invoked from MyMethod like this
NSArray* args = [NSArray arrayWithObjects:arg1, target, NSStringFromSelector(mySelector), nil];
NSThread* mythread= [[[NSThread alloc] initWithTarget:self selector: @selector(MyThreadRun:) object:args] autorelease];
[MyThreadRun start];
In the end of MyThreadRun, I try to invoke a function in the class which has called MyMethod t开发者_开发技巧o initiate the thread to begin with, like this:
NSObject* callbackTarget = [args objectAtIndex:1];
NSString* selector = [args objectAtIndex:2];
[callbackTarget performSelector:NSSelectorFromString(selector) withObject:calculationResult afterDelay:0];
I have a break point on the method that selector is pointing at, and it is never hit.
If I hard code the method name, like this
[callbackTarget updateWithResult:calculationResult]
it works fine.
What is there I need to know about performSelector?
The context where performSelector:withObject:afterDelay:
is getting invoked is the culprit. Here's what's going on.
Some members of the performSelector
... family, like this one, don't perform the selector right away; they queue up an invocation on the current run loop, so that it happens after your fn returns, the next go-round of the run loop. According to apple: "Specifying a delay of 0 does not necessarily cause the selector to be performed immediately. The selector is still queued on the thread’s run loop and performed as soon as possible."
Normally this is fine and expected. But your code is calling it on a thread that you started manually... and such threads don't keep their run loop going repeatedly the way the main thread does. They invoke the selector specified at creation once, and exit. So: your code queues up an invocation of your callback selector, but then the thread exits; and its run loop is thrown away without ever running... so your queued invocation never happens.
What you probably need is performSelectorOnMainThread:withObject:waitUntilDone:
, since you may want the callback to happen on the thread that invoked the MyMethod
method in the first place, which is presumably the main thread.
More generally, threading is very tricky stuff. I highly recommend checking out NSOperationQueue
, NSBlockOperation
, and related techniques - they can remove a great deal of the pain.
Is
NSString* selector = [args objectAtIndex:2];
equal to updateWithResult or updateWithResult:?
They're two different methods. You want the one with the colon.
Remove the "afterDelay:0" and your code works. Also "[MyThreadRun start]" should be "[mythread start]".
精彩评论