Last active
December 17, 2015 17:59
-
-
Save janodev/5650452 to your computer and use it in GitHub Desktop.
Different ways to execute a block property. This runs in CodeRunner. Replace one of the #ifdef X below with #ifdef YES, and comment person = nil;.
This file contains hidden or 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
int main(int argc, const char *argv[]) | |
{ | |
@autoreleasepool | |
{ | |
Person *person = [[Person alloc] initWithName:@"Alice"]; | |
[person execute:person.salute delay:1]; | |
person = nil; | |
NSLog(@"nil'ed"); | |
for (int i=3; i>0; i--) { | |
NSLog(@"."); | |
NSDate *oneSecond = [NSDate dateWithTimeIntervalSinceNow:1]; | |
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:oneSecond]; | |
} | |
} | |
} |
This file contains hidden or 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> | |
#undef X | |
typedef void (^salute_t)(); | |
@interface Person : NSObject | |
@property (nonatomic,copy) NSString *name; | |
@property (nonatomic,copy) salute_t salute; | |
-(void) execute:(salute_t)salute delay:(long long)seconds; | |
@end |
This file contains hidden or 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
@implementation Person | |
-(instancetype) initWithName:(NSString*)name { | |
self = [super init]; | |
if (!self){ | |
return nil; | |
} | |
self.name = name; | |
self.salute = ^{ NSLog(@"block undefined"); }; | |
#ifdef X | |
// Runs, but creates a retain cycle. | |
// #1 warning: capturing 'self' strongly in this block is likely to lead to a retain cycle | |
// #2 note: block will be retained by an object strongly retained by the captured object | |
/*2*/ self.salute = ^{ NSLog(@"%@", /*1*/ self->_name); }; | |
#endif | |
#ifdef X | |
// Compiler error. | |
// #1 error: dereferencing a __weak pointer is not allowed due to possible null | |
// value caused by race condition, assign it to strong variable first | |
__block __weak Person *weakSelf = self; | |
self.salute = ^{ NSLog(@"%@", /*1*/ weakSelf->_name); }; | |
#endif | |
#ifdef X | |
// This shows no warning, but it will dereference nil if the object is nil | |
// by the time the block is running. Dereferencing nil produces a segmentation fault. | |
__block __weak Person *weakSelf = self; | |
self.salute = ^{ | |
__strong Person *strongSelf = weakSelf; | |
NSLog(@"%@", strongSelf->_name); | |
}; | |
#endif | |
#ifdef X | |
// This executes the code or print a message, but if the object is deallocated when | |
// the execution starts (#1), it will lead to errors (in this case it prints nil). | |
__block __weak Person *weakSelf = self; | |
self.salute = ^{ | |
if (weakSelf){ | |
NSLog(@"%@", [weakSelf name]); /*1*/ | |
} else { | |
NSLog(@"object deallocated"); | |
} | |
}; | |
#endif | |
#ifdef YES | |
// This executes the code or print a message. If the object is deallocated when | |
// the execution starts (#1), the strong reference keeps the code running correctly. | |
__block __weak Person *weakSelf = self; | |
self.salute = ^{ | |
__strong Person *strongSelf = weakSelf; | |
if (strongSelf){ | |
NSLog(@"%@", strongSelf->_name); /*1*/ | |
} else { | |
NSLog(@"can't execute, object is gone"); | |
} | |
}; | |
#endif | |
return self; | |
} | |
-(void) execute:(salute_t)salute delay:(long long)seconds | |
{ | |
long long delaySeconds = 1; | |
long long delayNanoseconds = ((long long) delaySeconds)*NSEC_PER_SEC; | |
dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, delayNanoseconds); | |
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0UL); | |
dispatch_after(delay, queue, ^{ | |
salute(); | |
}); | |
NSLog(@"scheduled"); | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment