rai212
rai212

Reputation: 781

Use (or not) of self. in Objective-C properties

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

Answers (3)

jackslash
jackslash

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

Mike Z
Mike Z

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

Phillip Mills
Phillip Mills

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

Related Questions