I have a piece of code which is functionally equivalent to:
self.myProperty = [[MyClass alloc] initWithBla:bla blur:blur];
self.myProperty = [[MyClass alloc] initWithBla:bla blur:blur];
I'm not actually doing this twice in a row as illustrated above, but it's effectively what's happening. My question is, does this cause any memory leaks under ARC Objective C? Is the memory allocated for self.myProperty
in the first invocation reclaimed before self.myProperty
is reassigned to point at a newly allocated instance of MyClass
?
There's no leak in the property implementation, and as long as you're using ARC, no leak where you're assigning to the property either.
Calling:
self.myProperty = something
invokes a generated accessor that goes something like this (assuming _myProperty
is the backing ivar for your property):
- (void)setMyProperty:(MyClass *)anInstance
{
if (_myProperty == anInstance)
return;
[_myProperty release];
_myProperty = [anInstance retain];
}
The object formerly held by the property is released, so it doesn't leak here. And if you're using ARC, the code generated by the compiler works the same way.
You're correct in noting the potential for a leak, though not (as far as I can tell) where you suspect.
self.myProperty = [[MyClass alloc] initWithBla:bla blur:blur];
This creates a new object with a retain count of +1 and assigns it to the property (which then retains it again: +2). So, your code here still has an ownership reference to that object. When you repeat that line, you've orphaned the first reference, which you still own -- if you're using ARC, you're fine: it makes sure that object gets released. If not, that orphaned object is still retained: you do indeed have a leak. The appropriate non-ARC thing to do would be:
self.myProperty = [[[MyClass alloc] initWithBla:bla blur:blur] autorelease];
But, again, using ARC you're just fine.
To address a related question from comments: this is still okay -- but only under ARC -- if you're assigning to a local variable instead of to self.myProperty
. When you write:
id myLocalVar;
myLocalVar = [[MyClass alloc] initWithBla:bla blur:blur];
myLocalVar = [[MyClass alloc] initWithBla:bla blur:blur];
the compiler turns it into:
__strong id myLocalVar; // variables are strong by default
myLocalVar = [[MyClass alloc] initWithBla:bla blur:blur];
[myLocalVar release]; // ARC inserts release before myLocalVar is reassigned to another object
myLocalVar = [[MyClass alloc] initWithBla:bla blur:blur];
// ... sometime later ...
[myLocalVar release]; // ARC inserts another release when myLocalVar goes out of scope
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With