sending the delegate methods asynchronously - iPhone
I have defined a protocol like this:
@protocol RSSItemParserDelegate <NSObject>
- (void)RSSItemParser:(RSSItemParser *)pa开发者_JAVA技巧rser
didEndParsingSuccesfully:(BOOL)success;
@end
And I am calling this method when some parsing is finished, on success YES and on failure NO, like this:
[delegate RSSItemParser:self didEndProcessSuccesfully:NO];
But I would like it to run in the main thread asynchronously. How can I do this?
I think performSelectorOnMainThread:withObject:waitUntilDone:
would work with a solely argument method, but how about methods with two arguments like mines?
specially when working with AVFoundation and CoreVideo there are a lot of delegates methods that have more than 2 arguments, I wonder how are they called.
Thanks
Ignacio
SEL action = @selector(actionWithFoo:bar:baz:);
NSInvocation * i = [NSInvocation invocationWithMethodSignature:[target methodSignatureForSelector:action]];
[i retainArguments];
[i setTarget:target];
[i setAction:action];
[i setArgument:&foo atIndex:2];
[i setArgument:&bar atIndex:3];
[i setArgument:&baz atIndex:4];
[i performSelectorOnMainThread:@selector(invoke) withObject:nil waitUntilDone:NO];
Much easier and more extensible to just use a dictionary.
There are plenty of ways to do this. You could use the NSInvocation
API to create an invocation object that you then use one of the performSelector...
methods on (because invoke
and its kin take 0 or 1 parameters). Or, you could create an internal wrapper method that takes a single "context" object (a struct or dictionary) that wraps up all the values you need to pass to your delegate. Then, perform that method on the main thread and unpack the context values to pass them to your actual delegate method. Or, you can just pass the context object to your delegate directly and let it do the unpacking.
The easy way is to make a method that only needs one argument. In you case, make a delegate call method:
-(void) invokeDelegateWithDidEndProcessSuccesfully:(NSNumber)success {
[delegate RSSItemParser:self didEndProcessSuccesfully:[success boolValue]];
}
Then use it:
-(void) didEndParsingSuccesfully:(BOOL)success {
[self performSelectorOnMainThread:@selector(invokeDelegateWithDidEndProcessSuccesfully) withObject:[NSNumber numberWithBool:success] waitUntilDone:NO];
}
The hard way is to use an NSInvocation to handle an arbitrary number of arguments. None of the arguments are implicitly retained.
精彩评论