Tutorial :sending the delegate methods asynchronously - iPhone



Question:

I have defined a protocol like this:

@protocol RSSItemParserDelegate <NSObject>  - (void)RSSItemParser:(RSSItemParser *)parser  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


Solution:1

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.


Solution:2

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.


Solution:3

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.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »