• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: NSTimer memory management
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: NSTimer memory management


  • Subject: Re: NSTimer memory management
  • From: Jeff Johnson <email@hidden>
  • Date: Wed, 22 Sep 2010 20:50:34 -0500

It might be informative to see the entire backtrace and/or the entire source for the class, but in any case, I believe that the issue is "target:self". According to the NSTimer documentation, "The target object is retained by the timer and released when the timer is invalidated."

Your object retains the timer, and the timer retains your object. That is obviously a kind of retain cycle. What can happen is that your app gets into a situation where the only thing that retains a reference to your object is its own theTimer ivar. When the timer is invalidated, it releases your object (the target), and at that point it has a 0 retainCount, so your object is immediately deallocated. Then, boom!

The NSTimer API is somewhat unfortunate. It would probably be better to have a delegate API where the delegate is not retained. However, that ship has sailed. What you need to do is avoid the retain cycle. What I sometimes do is to create a private timer target that posts an NSNotification when the timer fires, and then your owning object with theTimer ivar is added as an observer of the notification. Your object is the owner of both the timer and the timer target, but there is no retain cycle.

-Jeff


On Sep 22, 2010, at 6:38 PM, email@hidden wrote:

> Hi,
>
> Is this an over-release?
>
> timer = [ [NSTimer scheduledTimerWithTimeInterval: ...] retain];
> ...
> [timer invalidate];
> [timer release];
>
> I've seen this pattern so many times I figured it was correct,
> although it doesn't seem to comply with the memory management rules
> (i. e. the timer is first implicitly released when invalidated, then
> explicitly released again).This never caused a problem on my Intel,
> but now I got several crash reports indicating an over-release on X86:
>
> Thread 0 Crashed:  Dispatch queue: com.apple.main-thread
> 0   com.apple.CoreFoundation      	0x92752c94 CFRelease + 196
> 1   com.apple.CoreFoundation      	0x927c97c1 __CFRunLoopTimerDeallocate + 33
> 2   com.apple.CoreFoundation      	0x92752e31 _CFRelease + 353
> 3   myApp                      	0x0000878a 0x1000 + 30602 // =
> invalidateTimer method
>
> Can someone please help clarify? This is my full code:
>
> - (void)invalidateTimer
> {
> 	if ( [theTimer isValid] ) {
> 		[theTimer invalidate];
> 		[theTimer release]; // crashes here
> 		theTimer = nil;
> 	}
> }
>
> - (void)startTimer
> {
> 	[self invalidateTimer];
> 	theTimer = [[NSTimer scheduledTimerWithTimeInterval:300 target:self
> selector:@selector(timerFireMethod:) userInfo:nil repeats:NO] retain];
> }


_______________________________________________

Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

  • Follow-Ups:
    • Re: NSTimer memory management
      • From: Andreas Grosam <email@hidden>
    • Re: NSTimer memory management
      • From: Scott Ribe <email@hidden>
References: 
 >NSTimer memory management (From: "email@hidden" <email@hidden>)

  • Prev by Date: Re: NSTimer memory management
  • Next by Date: [ANN] Release: NanoStore 1.0 for Mac and iOS
  • Previous by thread: Re: NSTimer memory management
  • Next by thread: Re: NSTimer memory management
  • Index(es):
    • Date
    • Thread