Last active
December 17, 2015 07:48
-
-
Save janodev/5575264 to your computer and use it in GitHub Desktop.
NSTimer with safe release. Credits to Effective Objective-C 2.0.
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, char *argv[]) { | |
@autoreleasepool { | |
TimerExample *timer = [TimerExample new]; | |
[timer startTicking]; | |
NSDate *timeout = [NSDate dateWithTimeIntervalSinceNow:5]; | |
while ([timeout timeIntervalSinceNow]>0) { | |
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode | |
beforeDate:[NSDate dateWithTimeIntervalSinceNow:1]]; | |
} | |
[timer stopTicking]; | |
} | |
} |
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> | |
@interface NSTimer (BlockSupport) | |
+ (NSTimer*)scheduledTimerWithTimeInterval:(NSTimeInterval)interval | |
block:(void(^)())block | |
repeats:(BOOL)repeats; | |
@end | |
@implementation NSTimer (BlockSupport) | |
+ (NSTimer*)scheduledTimerWithTimeInterval:(NSTimeInterval)interval | |
block:(void(^)())block | |
repeats:(BOOL)repeats | |
{ | |
return [self scheduledTimerWithTimeInterval:interval | |
// The class will be retained, not the instance. | |
// The Class object is a singleton so it doesn't matter. | |
target:self | |
selector:@selector(blockInvoke:) | |
// userInfo is retained while the block is valid | |
userInfo:[block copy] // make it a heap block | |
repeats:repeats]; | |
} | |
+ (void)blockInvoke:(NSTimer*)timer { | |
void (^block)() = timer.userInfo; | |
if (block) { | |
block(); | |
} | |
} | |
@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
// This example class retains NSTimer as an instance variable. | |
// NSTimer only retains self inside the block and only during the block duration. | |
// If the instance of the class is released, the timer is invalidated and released, | |
// and the class is deallocated as soon as the block is not running. | |
// If timer is not invalidated in the class dealloc: | |
// - the class and its NSTimer instance gets released, | |
// - the timer is not released because retainCount won't be 0 while it is valid, | |
// - the timer won't call anything because the __weak variable will be nil. | |
@interface TimerExample : NSObject | |
- (void)startTicking; | |
- (void)stopTicking; | |
@end | |
@implementation TimerExample { | |
NSTimer *_tickTimer; | |
} | |
- (id)init { | |
return [super init]; | |
} | |
- (void)dealloc { | |
[_tickTimer invalidate]; | |
} | |
- (void)stopTicking { | |
[_tickTimer invalidate]; | |
_tickTimer = nil; | |
} | |
- (void)startTicking { | |
__weak TimerExample *weakSelf = self; // avoids retain | |
_tickTimer = [NSTimer | |
scheduledTimerWithTimeInterval:1.0 | |
block:^{ | |
// Creates a strong reference to keep the | |
// instance alive for the duration of the block. | |
// If class is deallocated and timer is not invalidated, weakSelf will be nil. | |
TimerExample *strongSelf = weakSelf; | |
[strongSelf tick]; | |
} | |
repeats:YES]; | |
} | |
- (void)tick { | |
NSLog(@"poll"); | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment