Last active
December 18, 2015 12:59
-
-
Save beccadax/5787175 to your computer and use it in GitHub Desktop.
Allows you to add a "vulture": a block that will be executed when the object it's attached to is deallocated.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
@interface NSObject (addVulture) | |
// Do NOT use a block that captures this object. | |
// If you capture it strongly, you'll create a retain cycle. | |
// If you capture it weakly, you'll just get nil. | |
// If you capture it unsafely, you'll start calling methods on a mostly-dealloced object! | |
- (void)addVultureWithBlock:(dispatch_block_t)block; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "ArchVulture.h" | |
#import <objc/runtime.h> | |
@interface ArchVulture: NSObject | |
- (id)initWithBlock:(dispatch_block_t)block nextVulture:(ArchVulture*)nextVulture; | |
@property (copy) dispatch_block_t block; | |
@property (strong) ArchVulture * nextVulture; | |
@end | |
@implementation ArchVulture | |
- (id)initWithBlock:(dispatch_block_t)block nextVulture:(ArchVulture*)nextVulture { | |
if((self = [super init])) { | |
_block = [block copy]; | |
_nextVulture = nextVulture; | |
} | |
return self; | |
} | |
- (void)dealloc { | |
_block(); | |
} | |
@end | |
@implementation NSObject (addVulture) | |
- (void)addVultureWithBlock:(dispatch_block_t)block { | |
// Make sure our ArchVulture objects aren't put in the parent autorelease pool, | |
// giving them a longer lifetime than intended. | |
@autoreleasepool { | |
ArchVulture * currentVulture = objc_getAssociatedObject(self, _cmd); | |
ArchVulture * newVulture = [[ArchVulture alloc] initWithBlock:block nextVulture:currentVulture]; | |
objc_setAssociatedObject(self, _cmd, newVulture, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
} | |
} | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "ArchVulture.h" | |
int main(int argc, char *argv[]) { | |
@autoreleasepool { | |
NSObject * owner = [NSObject new]; | |
[owner addVultureWithBlock:^{ | |
NSLog(@"He's dead, Jim!"); | |
}]; | |
owner = nil; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment