开发者

The NSTimer that doesn't invalidate (or a weird memory problem I can't solve)

I'm having a huge problem with the NSTimer object. I can't explain myself this behavior, and I will try to explain as best as I can.

I have a function in my view which is called placeAdvertisement. In this function there are multiple operations with static methods that uses as parameter one of my objects (another view):

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 ...];

}

The last timer calls to another function, called quitAdvertisement, but he never gets called (when the failure is produced). The code seems to 开发者_如何学JAVAwork well in normal conditions, the advertisement controller works correctly, the banner is placed and the timer calls adsTimer, which quits the banner.

The problem appears if a pop the view (returning back) and the push another one again. Once the view is loaded I push a button that fires the code placed before. The code executes well, but in "the middle" of the execution, in [Advertisement operation1: self.adsController] appears EXC_BAD_ACCESS:

[MyController AdvertisementController]: message sent to deallocated instance 0x4e9b420

It's like in the middle of the code, my object gets deallocated. I don't have any code that calls release of the object, just the dealloc, which has not been called for this instance of the view (Has been called for the previous view, which was popped up).

How can be this possible? Is there any way to debug that in better conditions?

I've used NSZombieEnabled.

Thanks!

***Little edit for the comments***

  1. AdsController is allocated like:

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

After in dealloc method:

[self.adsController release];

[super dealloc];
  1. Respect to the timer:

    It is allocated with repeat NO. After in dealloc:

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

Is this correct?


From the code posted it looks as if when you 'pop' this view, there may still be an NSTimer valid that will be retaining its target. You could try invalidating the NSTimer [[self adsTimer] invalidate] in your viewWillDisappear: method (assuming you have a viewController - and if you don't, I'd recommend using one).

Tricky to diagnose from the code you have provided - while brevity is great, in this case a bit more might be helpful.


[NSTimer scheduledTimerWithTimeInterval] will add the timer to the current run loop. If the current thread is a background thread, it's possible that the thread has ended and the timer will never get fired. Try to add the timer to the main run loop.


Just to clarify what was the problem.

There was one NSNotification that was beign pushed only if the timer was active. This led me to believe that the problem was in the timer, but was the notification beign captured by a form that was released.

So, it's important to be very carefully removing the observer from any notification when a form is poped out.

I just want to thank your help.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜