Reputation: 1
According to my understanding of the "rules" for managing memory via retain/release, if you alloc/copy/retain an object, you must always (eventually) release it:
id foo = [[MyClass alloc] init];
id bar = [[MyClass alloc] init];
[bar takeOwnership:foo]; //bar retains foo
[foo release]; //I'm done with it now, so I release it
What do I do if I want to create foo inline instead, like this:
id bar = [[MyClass alloc] init];
[bar takeOwnership:[[MyClass alloc] init]];
I obviously can't release the object formerly known as foo when I allocate it, and without a reference I can't release it later, either. In effect, taking the "if you own it you must release it" approach seems to imply that you cannot allocate an object inline if you don't want it to end up leaking down the line.
So: Is it really verboten to allocate something inline? While the above example is a little contrived and the obvious solution there is to just not do it, it seems to me that there would be situations where it would be semantically desirable to be able to do so (in fact, I find myself in such a situation). In those cases - that is, assuming I want to be able to allocate objects inline as shown above - is there a way to do so without totally breaking the "normal" case where the object isn't allocated inline?
I can provide details on what I'm trying to do if they would be helpful, but hopefully the above gets my question across.
Upvotes: 0
Views: 226
Reputation: 162712
[bar takeOwnership:[[MyClass alloc] init]];
If you are using ARC (which you should be), you don't do anything different. It "just works".
If you are using manual-retain-release (MRR), then:
[bar takeOwnership:[[[MyClass alloc] init] autorelease]];
Note that autorelease pressure can be a performance problem; i.e. you might want to avoid the inline case w/autorelease for that reason. However, unless you are going through this code path 100s/1000s of times prior to the pool being drained, don't worry about it.
Upvotes: 6