Sometimes, one is not enough. There is a two argument non-thread version, here. So why not invent our own two-argument threaded version?
We can add this easily enough to the base NSObject class by opening a new category on it just for the purpose.
Here's how...
1. Define our API
We open a category on NSObject (note the category name in brackets)
@interface NSObject (PGPerformSelectorOnMainThreadWithTwoObjects)- (void) performSelectorOnMainThread:(SEL)selector withObject:(id)arg1 withObject:(id)arg2 waitUntilDone:(BOOL)wait;@end
Naturally, it follows the existing performSelector API signatures, but just adds our extra withObject: argument.
2. Implement it
Here's the secret sauce. Careful application of NSMethodSignature, and NSInvocation.
@implementation NSObject (PGPerformSelectorOnMainThreadWithTwoObjects)- (void) performSelectorOnMainThread:(SEL)selector withObject:(id)arg1 withObject:(id)arg2 waitUntilDone:(BOOL)wait{NSMethodSignature *sig = [self methodSignatureForSelector:selector];if (!sig) return;NSInvocation* invo = [NSInvocation invocationWithMethodSignature:sig];[invo setTarget:self];[invo setSelector:selector];[invo setArgument:&arg1 atIndex:2];[invo setArgument:&arg2 atIndex:3];[invo retainArguments];[invo performSelectorOnMainThread:@selector(invoke) withObject:nil waitUntilDone:wait];}@end
That's it.
Now you have your own simple way to invoke a call to selector on the main thread from wherever you are in your code. Handy.
2 comments:
neat trick, but a bit "overthinking"
just adding a small wrapper around the selector you wish to perform, to accept an NSArray of objects, and you are done to process as many objects as you need
performSelectorOnMainThread:@selector(mySelectorWithArgumentArray:)withObject:[NSArray arrayWithObjects:object1, object2, object3,...., objectN, nil] waitUntilDone:NO];
Not at all. There may be existing selectors you want to perform with that many parameters, that you cannot modify.
In that case, you'd have to write an NSArray shim for each one, perhaps in a category on the object (solution that scales badly).
Or use my extra perform method (solution that scales well).
Post a Comment