Skip to content

Instantly share code, notes, and snippets.

@bnickel
Last active August 8, 2016 01:20
Show Gist options
  • Save bnickel/98082385f605913fb42e to your computer and use it in GitHub Desktop.
Save bnickel/98082385f605913fb42e to your computer and use it in GitHub Desktop.
Sometimes, it's just worth it to accept the risk and do UIKit operations on a background thread; you just have to manage those risks. This category prints to the log any time you accidentally mess with setAnimationsEnabled: from a background thread and lets you set a breakpoint at SEViewAlertForUnsafeBackgroundCalls to inspect the call stack. Yo…
#import <UIKit/UIKit.h>
#import <objc/runtime.h>
#ifdef DEBUG
void SEViewAlertForUnsafeBackgroundCalls() {
NSLog(@"----------------------------------------------------------------------------------");
NSLog(@" ");
NSLog(@"Background call to setAnimationsEnabled: detected. This method is not thread safe.");
NSLog(@"Set a breakpoint at SEUIViewDidSetAnimationsOffMainThread to inspect this call.");
NSLog(@" ");
NSLog(@"----------------------------------------------------------------------------------");
}
@implementation UIView (BadBackgroundBehavior)
+ (void)load
{
method_exchangeImplementations(class_getInstanceMethod(object_getClass(self), @selector(setAnimationsEnabled:)),
class_getInstanceMethod(object_getClass(self), @selector(SE_setAnimationsEnabled:)));
}
+ (void)SE_setAnimationsEnabled:(BOOL)enabled
{
if (![NSThread isMainThread]) {
SEViewAlertForUnsafeBackgroundCalls();
}
[self SE_setAnimationsEnabled:enabled];
}
@end
#endif
@hewigovens
Copy link

This works for me

+ (void)load {
    method_exchangeImplementations(class_getClassMethod([self class], @selector(setAnimationsEnabled:)),
                                   class_getClassMethod([self class], @selector(xx_setAnimationsEnabled:)));
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment