Reputation: 4946
I am trying to really understand some memory management issues. And found this question, which partially answers the question I have.
For example, In MyObject I have an instance variable declared as a property and is properly synthesized in the implementation file:
@interface MyObject : NSObject
...
ObjectA objA;
...
@property (nonatomic, retain) ObjectA *objA;
@end
At some arbitrary point, I instantiate objA. I know self.objA = _objA;
calls the synthesized accessor. Which, logically, means self.objA = [[ObjectA alloc] init];
would lead to a memory leak, since the retain count would be one more than intended (I know checking the retain count directly is not an accurate way of checking how long an object is going to be in memory).
Does objA = [[ObjectA alloc] init;
also call the setter, and possibly lead to a memory leak?
Upvotes: 2
Views: 507
Reputation: 76842
objA = [[ObjectA alloc] init];
does not use the setter method but sets the instance variable directly. So the retain count would be 1, from the alloc
.
Upvotes: 2
Reputation: 2999
Calling the property name without "self." skips the setter and updates the instance variable directly.
To avoid the confusion and potential memory leaks, I like to rename the instance variable of the synthesized property like this:
@synthesize objA = _objA;
Your class would look like this:
@interface MyObject : NSObject
...
@property (nonatomic, retain) ObjectA *objA;
@end
Now, if you forget "self.", you'll get a compiler error and it'll be more explicit about which variable you're actually using.
Upvotes: 4
Reputation: 30846
Assigning the result of an alloc
/init
to the raw instance variable is perfectly acceptable and is recommended for setting instance variables in an initialization method. To avoid leaking memory when using the synthesized setters you can take two approaches.
1. Autorelease
self.objA = [[ObjectA alloc] init] autorelease];
Going through setter of 'retain' property increments the retain count. The alloc/init also incremented the retain count but is balanced by the autorelease meaning that it will be decremented by 1 and the end of the current event loop.
2. Assign to temporary variable first
// +alloc/-init increments the retain count of objectA to 1
ObjectA objectA = [[ObjectA alloc] init];
// Synthesized setter calls retain on objectA, incrementing to 2.
self.objA = objectA;
// Decrement objectA's retain count to 1.
[objectA release];
Upvotes: 3