There is no leak in the implementation of the property, and as long as you use ARC, there is no leak in which you also assign the property.
Vocation:
self.myProperty = something
calls the created accessory, which looks something like this (assuming _myProperty
is the base ivar for your property):
- (void)setMyProperty:(MyClass *)anInstance { if (_myProperty == anInstance) return; [_myProperty release]; _myProperty = [anInstance retain]; }
An object previously held by the property is freed, so it does not flow here. And if you use ARC, the code generated by the compiler works the same way.
You correctly noticed the potential for a leak, although not (as far as I can tell) where you suspect.
self.myProperty = [[MyClass alloc] initWithBla:bla blur:blur];
This creates a new object while preserving the number +1 and assigns it to a property (which then saves it again: +2). Thus, your code here still has a reference to ownership of this object. When you repeat this line, you have orphaned the first link that you still own - if you use ARC, you are fine: it ensures that the object is released. If not, then the lost object is still saved: you really have a leak. The corresponding non-ARC item should be:
self.myProperty = [[[MyClass alloc] initWithBla:bla blur:blur] autorelease];
But, again, using ARC, you're just fine.
To answer a related question with comments: it's all the same, but only with ARC - if you assign a local variable instead of 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