This works, but is a bit of an anti-pattern. What I would do is throw an error if the thread the method is called on is not the main thread. It is the responsibility of the caller to make sure methods are called on the right threads, these sorts of hacks only encourage ugly code. Besides, if you rely on this, suddenly you're doubling the message dispatch overhead for every time you call this method.
If you really cant change the caller's behavior, you can try the following:
-(void)methodToBeRunOnMainThreadWithObj:(id)object {
dispatch_sync(dispatch_get_main_queue(), ^{
// code goes here
});
}
this will cause all code inside the dispatch block to be executed on the main thread, and the method will not return until it is complete. If you want the method to return immediately, you can use dispatch_async
instead. If you use dispatch_sync
, you can use this trick even on methods that have non-void return types.
This code also has the added benefit of supporting methods with arguments that are of non-object types (int
etc). It also supports methods with an arbitrary number of arguments, whereas performSelector:withObject:
and its sibling methods only support a limited number of arguments. The alternative is to set up NSInvocation
objects and those are a pain.
Note that this requires Grand Central Dispatch (GCD) on your platform.
void
, but OP seems to be looking for a general solution, andperformSelector
is not one. – Spannew