I’ve just been bitten again by how easy it is to accidentally retain self using Objective-C blocks.
After a little thought, I came up with a single line of code you can place in the header of your block that will root out most (all?) possible errors: id self = (id)0x1.
Here it is in action:
@implementation MyClass
@synthesize window;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
__block typeof(self) blockSelf = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1ull * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
id self = (id)0x1; // SHOULD result in compile-time warning: "unused variable 'self'"
blockSelf.window; // Fine
self.window; // Compile-time error: "request for member 'window' in something not a structure or union"
window; // Compile-time error: "'struct objc_object' has no member named 'window'"
NSLog(@"%@", blockSelf); // Fine
NSLog(@"%@", self); // No compile-time warnings or errors, but runtime EXC_BAD_ACCESS
});
}
@end