Reputation: 781
I've got a doubt about assigning values to properties in Objective-C. I've had a lot of problems of "misteriously missed" values, for example if I have this interface:
// MyClass.h
@interface MyClass : NSObject {
MyOtherClass *myVar;
}
@property (nonatomic, retain) MyOtherClass *myVar;
- (id)initWithValue:(NSString *)val;
And this implementation:
// MyClass.m
@implementation MyClass
@synthesize myVar;
- (id)initWithValue:(NSString *)val {
self = [super init];
if (self != nil) {
/** Do some stuff with val... **/
myVar = [method:val]; // Some method that returns a MyOtherClass value
}
return self;
}
At some point of the execution, the value of myVar disappears, changes or something else... And the solution is to change:
myVar = [method:val]; // Some method that returns a MyOtherClass value
for
self.myVar = [method:val]; // Some method that returns a MyOtherClass value
So... what is the diference between using self or not using it? I mean, it's clear that I've to use it because if not it will cause problems but I don't know why
Thank you in advance
Upvotes: 1
Views: 1789
Reputation: 8570
What method are you calling on val
?
I would imagine that when you do
myVar = [method:val]; // Some method that returns a MyOtherClass value
The result is an autoreleased object. That means that when your init method finishes your myVar
object is released and gets destroyed. The myVar
variable still points to the place in memory where the object was, but that memory could get filled with anything.
When you use the property setter method using the dot syntax like this
self.myVar = [method:val];
The setter method that is automatically synthesised for you by the compiler will send the object a retain message to keep it around.
You could also fix your code error like this:
myVar = [[method:val] retain]; // Some method that returns a MyOtherClass value
but its better to stick to the dot syntax.
Upvotes: 0
Reputation: 4111
This is a good example of why you should change your @synthesize
to @synthesize myVar = _myVar;
or some variation of that. Without doing that, it is possible to set your instance variable out from under you as a direct assignment of `myVar = nil" would bypass your setter.
Using the myVar = _myVar
strategy will cause the compiler to complain if you attempt to do myVar =
and will require you to call self.myVar
which will access your setter or getter.
The only place you should then use _myVar
is if you change the declaration of your setter or getter for that variable.
Upvotes: 1
Reputation: 31026
If you use self, you're using the property and it is marked with "retain". If you use the variable, you're bypassing the property, therefore no "retain". You could write myVar = [[someObject method:val] retain];
and get the same effect as the property.
Upvotes: 3