NSTimer可能的崩溃原因
我在使用NSTimer时遇到问题。 假设我有这样的结构:NSTimer可能的崩溃原因
ThreadedClass.m(包含的NSTimer *定时器;)
- (id) init {
if (self = [super init]) {
// do blablabla
[self launchAThread];
}
return self;
}
- (void) launchAThread {
[NSThread detachNewThreadSelector:@selector(selectorToMyThreadFunction)
toTarget:self
withObject:nil];
}
- (void) selectorToMyThreadFunction {
//I do my stuff in here
//Then i relaunch a Timer to call this function
//periodically but it has to be "atomic" so no
//repeating timer since i don't know the time
//this function will take
//I do some [self changeSomething];
[self restartTimer];
//MyThread ends here (and might be recreated by the Timer's bip
}
- (void)restartTimer {
if (![NSThread isMainThread]) {
[self performSelectorOnMainThread:@selector(restartTimer)
withObject:nil
waitUntilDone:NO];
return;
}
[timer invalidate];
[timer release];
timer = [[NSTimer scheduledTimerWithTimeInterval:interval
target:self
selector:@selector(launchWithTimer:)
userInfo:nil
repeats:NO] retain];
}
- (void) launchWithTimer:(NSTimer *)theTimer {
if (theTimer == timer)
{
[timer release];
timer = nil;
[self launchAThread];
}
else
{
//Nothing to be done in here, a user launch a thread manually
}
}
因此,让我们假设类ALLOC它的用户,并在之后将其释放。我的计时器仍然活着,对象也一样(因为定时器有保留)。 当计时器启动时,它会执行[self launchAThread]
,然后计时器将自动失效并释放它,并释放我的对象,该对象现在有一个retainCount = 0 ...让我们再假设一次该对象被释放后,这将导致崩溃,我无法做到阻止它进入我脑海。
我同意,这是很多假设,但我很想知道是否有人已经有这个问题,他是如何解决它的。
感谢您的阅读,我希望我很清楚! :)
因为我正在做一个图书馆,我不能假设用户将调用清理功能任何时候。
因此,为了解决我的问题,我添加了一个新的“层”:一个新的类,将执行线程和计时器部分,以便我是这个类的用户,我知道我必须清理!
哟必须始终使您的计时器释放它之前无效。如果计时器是视图控制器的一部分,我总是在viewWillDisappear中使其无效。对我来说非常奇怪的是,NSTimers保留了他们的主人。我认为最好的方法是创建 - (void)cleanUp方法,它将使计时器失效并警告类的用户始终在发布之前使用cleanUp。如果有人知道更好的方式,我会很高兴。
只要你不使用重复计时器,为什么不使用dispatch_after
?您可以节省NSTimer对象的头痛和头顶。如果你坚持使用GCD,你也可以避免拨打detachNewThreadSelector:
。
我第一次使用cleanUp类功能。 我也有一个对象一个拥有对象B,它包含定时器 - 它保留了对象B.当对象A被释放时,它释放对象B,但B因为定时器保留它而继续生存。然后在解雇的方法,但计时器,我使用委托关系回调对象A→硬崩溃。这是对象A需要“清理”B的计时器的地方。这可能会导致其他问题,虽然如果其他对象也依赖于对象B.而且类A不应该也不可能知道类B的实现秘诀:-PI猜想一个好的解决方案可能是取消设置代理关系在释放之前是在A的dealloc中完成的,因为即使你释放它也不知道B是否会死亡 - 其他人可能保留了它(像D *** NSTIMER)... :-P
是的就是这样我现在正在做。但是就你而言,我想知道另一种方法,如果有的话)。无论如何感谢 – delannoyk 2012-02-24 17:05:26
由于我正在创建一个库,我不能认为用户会随时调用cleanUp函数。所以为了解决我的问题,我添加了一个新层:一个新的类,它将执行线程和计时器部分,以便我是这个类的用户,并且我知道我必须进行清理! – delannoyk 2012-02-27 17:00:10