NSTimer没有失效(或者我无法解决的奇怪的内存问题)

时间:2011-09-10 09:21:43

标签: objective-c ios ios4

我的NSTimer对象存在很大问题。我无法解释这种行为,我会尽力解释。

我的视图中有一个叫做placeAdvertisement的函数。在这个函数中,有多个静态方法操作,它们使用我的一个对象作为参数(另一个视图):

if (self.adsController == nil) {
    self.adsController = [[AdsController alloc] ...];
    [self.view addSubView: self.adsController.view;
}

if (banner != nil) {

    self.adsController.banner = banner;
    [self.adsController updateBanner];

    //If a previous timer is still working (because this method can be called multiple times) invalidate
    if (self.adsTimer != nil)
        [self.adsTimer invalidate];

    [Advertisement operation1: self.adsController];
    [Advertisement operation2: self.adsController];

    self.adsTimer = [NSTimer scheduledTimerWithTimeInterval: 5 ...];

}

最后一个计时器调用另一个名为quitAdvertisement的函数,但他永远不会被调用(当产生失败时)。代码似乎在正常情况下运行良好,广告控制器正常工作,横幅放置,计时器调用adsTimer,退出横幅。

如果弹出视图(返回)并再次按下另一个视图,则会出现问题。加载视图后,我按下一个按钮,触发之前放置的代码。代码执行得很好,但在执行的“中间”,在[Advertisement operation1:self.adsController]中出现EXC_BAD_ACCESS:

[MyController AdvertisementController]:发送到解除分配的实例0x4e9b420的消息

就像在代码中间,我的对象被取消分配。我没有任何调用对象释放的代码,只有dealloc,没有为这个视图实例调用过(已经被调用了以前的视图,它被加速了)。

怎么可能这样呢?有没有办法在更好的条件下调试它?

我使用过NSZombieEnabled。

谢谢!

***很少编辑评论***

1)AdsController分配如:

self.adsController = [[AdsController alloc] initWithNibName:nil bundle:nil];

在dealloc方法之后:

[self.adsController release];

[super dealloc];

2)尊重计时器:

It is allocated with repeat NO. After in dealloc:

if (self.adsTimer != nil) [self.adsTimer invalidate];

这是对的吗?

3 个答案:

答案 0 :(得分:1)

从发布的代码看起来好像当你'弹出'这个视图时,可能仍然有一个有效的NSTimer将保留其目标。您可以尝试在[[self adsTimer] invalidate]方法中使NSTimer viewWillDisappear:无效(假设您有一个viewController - ,如果不这样做,我建议使用一个)。

从您提供的代码中进行诊断时很棘手 - 虽然简洁性很好,但在这种情况下可能会有所帮助。

答案 1 :(得分:1)

[NSTimer scheduledTimerWithTimeInterval]会将计时器添加到当前运行循环中。如果当前线程是后台线程,则线程可能已经结束并且计时器永远不会被触发。尝试将计时器添加到主运行循环中。

答案 2 :(得分:0)

只是为了澄清问题所在。

只有在计时器处于活动状态时,才会有一个NSNotification被推迟。这让我相信问题出现在计时器中,但通知是由已发布的表单捕获的。

因此,当表格被填空时,非常小心地将观察者从任何通知中删除。

我只想感谢你的帮助。