我想将这个问题单独放在这里,与我的先前的问题“保留重复的NSTimer以供后续访问”分开,因为讨论已经进一步发展,用一个新的问题更加清晰,而不是再次编辑:
场景是,一个对象在viewDidLoad中创建了一个重复的NSTimer,一旦创建,NSTimer需要保持存在,以便其他方法可以访问它。
NSTimer *ti = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:@selector(updateDisplay:)
userInfo:nil
repeats:YES];
我明白当创建runloop时,runloop会拥有NSTimer,并在调用[ti invalidate];
后最终停止、移除并释放NSTimer。
由于我们需要在多个方法中访问NSTimer,因此我们需要一种保留对它的引用以供未来使用的方法,修改后的问题是:
// (1) Should the NSTimer be held using an owning reference (i.e.)
@property(nonatomic, retain) NSTimer *walkTimer;
[self setWalkTimer: ti];
...
...
// Cancel method
[[self walkTimer] invalidate;
[self setWalkTimer:nil];
...
...
// dealloc method
[walkTimer release];
[super dealloc];
.
// (2) Should the NSTimer be held using a weak reference (i.e.)
@property(nonatomic, assign) NSTimer *walkTimer;
[self setWalkTimer: ti];
...
...
// Cancel method
[[self walkTimer] invalidate];
[self setWalkTimer:nil];
...
...
// dealloc method
[super dealloc];
.
// (3) Use an iVar and rely on the runLoop holding (i.e. retaining) the timer
NSTimer *walkTimer;
NSTimer *walkTimer = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:@selector(updateDisplay:)
userInfo:nil
repeats:YES];
...
...
// Cancel method
[walkTimer invalidate];
walkTimer = nil;
.
// (4) Something not listed above ...
我很高兴只用(1) (2) (3)或(4),因为在其他帖子中已经有很多关于哪种方式最好的讨论。看起来有很多不同的答案,所以我希望这个更具体的问题能够帮助集中讨论在这种情况下可能是最佳实践的内容。
编辑:
作为一个副注,在Apple NSTimer 类引用中,五个示例代码项目中有四个使用了被分配给保留属性的NSTimer。以下是类参考示例显示的示例:
@property (nonatomic, retain) NSTimer *updateTimer;
updateTimer = [NSTimer scheduledTimerWithTimeInterval:.01 target:self selector:@selector(updateCurrentTime) userInfo:p repeats:YES];
...
...
// Cancel
[updateTimer invalidate];
updateTimer = nil;
...
...
// Dealloc method
[super dealloc];
[updateTimer release];
需要注意的是,在这些例子中,Apple直接分配了iVar而不使用属性设置器。
retain
,但实际上计时器并没有被保留 - 在dealloc
中的最后一个release
应该会导致崩溃。我有什么遗漏吗? - Daniel Dickisondealloc
实际上从未被调用——这有些说得通,因为对象似乎应该与应用程序一样长寿... 话虽如此,你是正确的:这完全是错的。 - danyowdee