hua*_*nyu 2 objective-c nstimer dealloc ios
考虑具有强(或弱,相同)NSTimer属性的视图控制器:
__weak __typeof(self) ws = self;
self.timer = [NSTimer scheduledTimerWithTimeInterval:2 target:ws selector:@selector(timerTigger:) userInfo:nil repeats:YES];
Run Code Online (Sandbox Code Playgroud)
但是为什么这个视图控制器不会调用dealloc方法,无论是传递strong还是weak引用self?
这是详细的代码:
#import "SecondViewController.h"
@interface SecondViewController ()
@property (nonatomic, weak) NSTimer *timer;
@end
@implementation SecondViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
__weak __typeof(self) ws = self;
self.timer = [NSTimer scheduledTimerWithTimeInterval:2 target:ws selector:@selector(timerTigger:) userInfo:nil repeats:YES];
}
- (void)timerTigger:(id)timer {
NSLog(@"do someting");
}
- (void)dealloc {
NSLog(@"SecondViewController dealloc");
}
Run Code Online (Sandbox Code Playgroud)
Rob*_*Rob 11
NSTimer保持对它的强引用,target直到计时器失效.您无法选择是NSTimer建立弱引用还是强引用.当你传递一个弱引用时,只要ws不是nil你启动计时器的时间(在这种情况下很明显不会),NSTimer就会建立对指向的任何target指针的强引用.是否scheduledTimerWithTimeInterval建立一个强引用或弱引用并不是你传递给它的指针的一些固有特性,而是一个问题,即该方法对它所提供的指针的作用.
要修复此强引用行为,您可以采用以下模式之一:
使用基于块的再现NSTimer并在块内使用"弱自我"模式;
@interface ViewController ()
@property (nonatomic, weak) NSTimer *timer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
typeof(self) __weak weakSelf = self;
self.timer = [NSTimer scheduledTimerWithTimeInterval:2 repeats:true block:^(NSTimer * _Nonnull timer) {
[weakSelf timerTigger];
}];
}
- (void)timerTigger {
NSLog(@"do something");
}
- (void)dealloc {
[self.timer invalidate];
}
@end
Run Code Online (Sandbox Code Playgroud)使用GCD计时器,它也是基于块的,因此也可以很容易地配置为不保持强引用; 要么
@interface ViewController ()
@property (nonatomic, strong) dispatch_source_t timer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
typeof(self) __weak weakSelf = self;
self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
dispatch_source_set_timer(self.timer, DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
dispatch_source_set_event_handler(self.timer, ^{
[weakSelf timerTigger];
});
dispatch_resume(self.timer);
}
- (void)timerTigger {
NSLog(@"do something");
}
@end
Run Code Online (Sandbox Code Playgroud)使用NSTimer与目标/选择器,但是invalidate定时器某处逻辑(例如viewDidDisappear等).
@interface ViewController ()
@property (nonatomic, weak) NSTimer *timer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerTigger:) userInfo:nil repeats:true];
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
[self.timer invalidate];
}
- (void)timerTigger:(NSTimer *)timer {
NSLog(@"do something");
}
@end
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
1348 次 |
| 最近记录: |