Các [NSTimer scheduledTimerWithTimeInterval:...]
vẫn giữ được mục tiêu, vì vậy nếu mục tiêu là tự, sau đó bạn thể hiện của các lớp mô hình sẽ không bao giờ được deallocated.
Như một giải pháp thay thế, người ta có thể sử dụng một đối tượng riêng biệt (được gọi là TimerTarget
trong ví dụ sau). TimerTarget
có tham chiếu yếu tới ModelClass
để tránh chu kỳ lưu giữ.
"Lớp trợ giúp" này trông như thế này. Mục đích duy nhất của nó là để chuyển tiếp sự kiện hẹn giờ đến "đích thực".
@interface TimerTarget : NSObject
@property(weak, nonatomic) id realTarget;
@end
@implementation TimerTarget
- (void)timerFired:(NSTimer*)theTimer
{
[self.realTarget performSelector:@selector(timerFired:) withObject:theTimer];
}
@end
Bây giờ, trong lớp mô hình của bạn, bạn có thể tạo một bộ đếm thời gian và vô hiệu hóa nó trong dealloc
:
@interface ModelClass()
@property(strong, nonatomic) NSTimer *timer;
@end
@implementation ModelClass
- (id)init
{
self = [super init];
if (self) {
TimerTarget *timerTarget = [[TimerTarget alloc] init];
timerTarget.realTarget = self;
self.timer = [NSTimer scheduledTimerWithTimeInterval:1
target:timerTarget
selector:@selector(timerFired:)
userInfo:nil repeats:YES];
}
return self;
}
- (void)dealloc
{
[self.timer invalidate]; // This releases the TimerTarget as well!
NSLog(@"ModelClass dealloc");
}
- (void)timerFired:(NSTimer*)theTimer
{
NSLog(@"Timer fired");
}
@end
Vì vậy, chúng tôi có
modelInstance ===> timer ===> timerTarget ---> modelInstance
(===> : strong reference, ---> : weak reference)
Lưu ý rằng không có (mạnh) tham chiếu từ bộ đếm thời gian đến thể hiện của lớp mô hình nữa.
Tôi đã thử nghiệm này với đoạn mã sau, mà tạo ra một thể hiện của ModelClass
và phát hành nó sau 5 giây:
__block ModelClass *modelInstance = [[ModelClass alloc] init];
int64_t delayInSeconds = 5.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
modelInstance = nil;
});
Output:
2013-01-23 23:54:11.483 timertest[16576:c07] Timer fired
2013-01-23 23:54:12.483 timertest[16576:c07] Timer fired
2013-01-23 23:54:13.483 timertest[16576:c07] Timer fired
2013-01-23 23:54:14.483 timertest[16576:c07] Timer fired
2013-01-23 23:54:15.483 timertest[16576:c07] Timer fired
2013-01-23 23:54:15.484 timertest[16576:c07] ModelClass dealloc
Tôi chưa bao giờ thực sự sử dụng này trước khi ... Khi tôi đang học Objective-C Tôi đã luôn nói rằng 'dealloc' hiếm khi được sử dụng nữa. Các thuộc tính của tôi có còn hợp lệ trong phương thức 'dealloc' không? – Nosrettap
Làm thế nào về dealloc? Có, họ sẽ được. Tôi đang gõ nó lên như một câu trả lời. –
Tuyệt! Nếu bạn đăng câu trả lời này, tôi sẽ chấp nhận nó – Nosrettap