Skip to content

Instantly share code, notes, and snippets.

@jerryhjones
Created September 25, 2012 04:18
Show Gist options
  • Save jerryhjones/3779961 to your computer and use it in GitHub Desktop.
Save jerryhjones/3779961 to your computer and use it in GitHub Desktop.
// NOTE: GameCenter does not guarantee that callback blocks will be execute on the main thread.
// As such, your application needs to be very careful in how it handles references to view
// controllers. If a view controller is referenced in a block that executes on a secondary queue,
// that view controller may be released (and dealloc'd) outside the main queue. This is true
// even if the actual block is scheduled on the main thread. In concrete terms, this code
// snippet is not safe, even though viewController is dispatching to the main queue:
//
// [object doSomethingWithCallback: ^()
// {
// dispatch_async(dispatch_get_main_queue(), ^(void)
// {
// [viewController doSomething];
// });
// }];
//
// UIKit view controllers should only be accessed on the main thread, so the snippet above may
// lead to subtle and hard to trace bugs. Many solutions to this problem exist. In this sample,
// I'm bottlenecking everything through "callDelegateOnMainThread" which calls "callDelegate".
// Because "callDelegate" is the only method to access the delegate, I can ensure that delegate
// is not visible in any of my block callbacks.
- (void)callSelf:(SEL)selector withArg:(id)arg error:(NSError*)err
{
assert([NSThread isMainThread]);
if([self respondsToSelector: selector])
{
if(arg != NULL)
{
[self performSelector: selector withObject: arg withObject: err];
}
else
{
[self performSelector: selector withObject: err];
}
}
else
{
NSLog(@"Missed Method");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment