Re: Unwanted retain
Re: Unwanted retain
- Subject: Re: Unwanted retain
- From: Dustin Voss <email@hidden>
- Date: Thu, 5 Feb 2004 15:20:31 -0800
On 5 Feb, 2004, at 9:27 AM, b.bum wrote:
On Feb 5, 2004, at 5:44 AM, Clark Cox wrote:
Actually, as I understand it, when you schedule the timer, and it is
added to the run loop, the run loop retains it. When you call
invalidate (thereby removing it from the runloop), the runloop does
indeed release the timer. So unless you explicitly retain the timer,
there is no need to release it as that will be taken care of by
invalidate.
While Clark might be correct, it is completely and totally irrelevant
to consider what the run loop might or might not be doing to the
retain count of the timer. Reading the documentation for NSTimer and
NSRunLoop, neither mention anything about retaining the timer. While
the Run Loop might retain the timer for its own purposes, that is none
of your business as a Cocoa developer! :-)
1. if [and only if] you retain anInstanceOfAnything, you must release
anInstanceOfAnything or autorelease anInstanceOfAnything. Otherwise,
there will be a leak. There is implied retains; copy, alloc, etc...
2. if you did not retain anInstanceOfAnything, you must not release
anInstanceOfAnything or autorelease anInstanceOfAnything to try and
compensate. To do so will likely cause your app to crash. See rule
#1.
3. if you want to return anInstanceOfAnything of anything from your
method, you must autorelease it. Unless you really really really know
what you are doing, use 'return [[anInstanceOfAnything retain]
autorelease];'.
4. if you want anInstanceOfAnything to survive until you decide it is
time for it to die, then you must retain anInstanceOfAnything.
5. if some other object retains anInstanceOfAnything, that is none of
your business. Seriously. If you feel that the other object is
holding on to anInstanceOfAnything for too long, then figure out how
to tell the other object that it no longer needs anInstanceOfAnything.
Do not steal the retain! See #1 and #2.
6. +alloc, -mutableCopy, and -copy return retained instances. Unless
documented otherwise, everything else that produces an instance of an
object will return an autoreleased instance.
7. Never ever ever call -dealloc directly except when implementing
-dealloc and, then, only call [super dealloc] at the end of your
implementation.
8. Threads do not change the rules. Threads just make the rules
harder to follow. There is one active release pool per thread.
Retain/release/autorelease is the same synchronization issue as
encountered with any other attempts to pass data/notifications between
threads. Don't get me started.
9. It is extremely unlikely that there is an undocumented
retain/release/autorelease bug in the Foundation or Cocoa. There may
be documented bugs (see release notes and documentation). The more
mature the API, the less likely there is a bug. If you suspect that
you have found a retain/release/autorelease bug in Foundation or
Cocoa, produce a minimal example demonstrating the bug and ask about
it here. If it is a bug, file a bug at http://bugreport.apple.com/.
10. Retain/release/autorelease is really simple unless you care too
much about what other objects are doing. Seriously. The
documentation will tell you if an anInstanceOfAnything is retained or
released or copied or whatever if it is expected that you need to
know. Otherwise, you should not care. See rules 1 through 9.
All of this revolves around encapsulation. A part of encapsulation
is isolation. To get back to the original example, an NSTimer
encapsulates the notion of invoking a method on a target at some later
point in time. It provides a nice API through which it encapsulates
and isolates said functionality.
This is all true. The reason I don't think timers should be released is
because you don't call [[NSTimer alloc] init], instead you call
[NSTimer timerWith...] or [NSTimer scheduledTimerWith...] and get an
autoreleased timer. But if you take that timer, and retain it in an
ivar, you would of course call release on it.
You are right in saying that we should not rely on NSRunLoop to retain
the timer. It IS none of our business, and if we want to keep the timer
in an instance variable, we should retain it, and release it in our
dealloc method.
My advice to Lorenzo was incorrect on this point, and I apologize.
Assuming he retained the timer he got back from [NSTimer whatever], he
should both invalidate and release it.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.