On Mar 3, 2011, at 10:10, Matt Neuburg wrote:

> What you *can* rely on is that a ***factory method*** will hand you an 
> autoreleased object. So, [NSArray array] hands you an autoreleased array; it 
> won't vanish right this second, but it will vanish when your code comes to an 
> end, unless you retain it. You may be confusing this with that. Even in that 
> case you don't have ownership; you just have some extra persistence time 
> while your code continues to run. And this makes sense, because there is no 
> other owning object.

EXCEPT:

What you say can't be literally true. In the non-factory-method case of a 
returned property value, you *do* have some extra persistence time, because you 
*must* have some extra persistence time, because you need to be able to retain 
the returned value before it disappears:

        id someValue = [someObject someProperty];
        [someValue retain]; // someValue must persist at least this long

Of course, in the simplest case where multiple threads aren't involved, this 
looks safe enough, because nothing should cause 'someValue' to dealloc before 
the retain.

So, the question arises: how long are you permitted to go before you need to do 
the retain? AFAIK there's no actual answer to that question, but the pragmatic 
answer has always been: until the next drain of an autorelease pool that might 
contain the object (that is, often, until you return to the main event loop), 
and that's a little hard to predict in the general case that might involve 
local autorelease pools.

What I'm trying to say is that deciding whether to be "safe"/"tedious" is, 
theoretically, guesswork. In practice, the usual heuristic is to assume a 
retained-autoreleased object, and to fix the crashes on a case by case basis -- 
which is what Gerriet just had to do.

EXCEPT:

> Suppose you've got an NSArray and you fetch its element objectAtIndex:0. And 
> suppose you now let go of the array (release) and it is destroyed. Do you 
> expect the fetched element to persist without your having retained it? You do 
> not; you know darned well that a collection doesn't behave like that. The 
> collection *owns* its elements and will release them when it is released. All 
> you got when you called objectAtIndex:0 was a pointer. If you want a share in 
> its ownership, you must *take* ownership.

And the one common zero-extra-persistence-time case that you didn't quite 
mention:

        id someValue = [someArray objectAtIndex: 0];
        [someArray removeObjectAtIndex: 0];
        [someValue retain]; // too late!

I think both of these are essentially different from Gerriet's case, because 
there is an obvious change-of-ownership "event" between getting the 
non-retained pointer and retaining it. The only real connection between the two 
scenarios is that you end up with a pointer to a possibly dead object, unless 
you take care.

AND:

Things are both better and worse under garbage collection. Worse, because there 
is no extra persistence time, because the GC thread could run at any moment. 
Better, because the the compile-time scoping of variables *usually* creates the 
effect of extra persistence time, until the run-time equivalent of the "}" of 
the block containing their declaration. Except when optimization shortens the 
effective scope. But that's a different discussion.


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to