开发者

Difference between self.instanceVar = X and instanceVar = X in Obj-c

开发者 https://www.devze.com 2023-02-20 14:00 出处:网络
For the following two lines in an obj-c class: self.instanceVar = X instanceVar = X Is the only difference that the \'self\' version calls the 开发者_JS百科synthesized \'setter\', whereas the latt

For the following two lines in an obj-c class:

self.instanceVar = X
instanceVar = X 

Is the only difference that the 'self' version calls the 开发者_JS百科synthesized 'setter', whereas the latter simply sets the instanceVar and doesn't go through the setter?

Thanks


Yes. The implication of this is that the synthesized getter will wrap additional code depending on how the property is specified - so use of assign / retain / copy along with nonatomic / atomic change the behaviour.


Imagine the following:

@property( retain ) NSString * myprop;

If you set it by self.myprop, the NSString instance will be retained.

If you set directly the instance variable, this will not be the case.

So always use the self., unless you're absolutely sure...


This is an excellent question and understanding the difference between setting a variable through its accessor rather than directly assigning it is very important.

Here's what happens: when you declare a @property (nonatomic, retain) NSString *variable in the header, you add a property to your object. Simple enough. Calling @synthesize does the following thing: it generates two methods in your class, setVariable: and getVariable. Of course, if you name your property "name", the methods will be setName: and getName.

Now, it is important for you to understand what happens in the setVariable: method. The method is declared something like this:

- (void)setVariable:(NSString *)theVariable {
    if (variable != nil) {
        [variable release];
    }

    // variable is the class member, 
    // theVariable is the object that was sent by the method parameter
    variable = [theVariable retain];
}

When you call self.variable = @"test"; you will actually call [self setVariable:@"test"] which is exactly the method that was generated by the @synthesize call!

When you call variable = @"test"; you do just that - you assign a string to a variable, without retaining it or anything.

If you were to call self.variable = nil the current value of the variable would be released and variable will be assigned to nil, but if you were to call variable = nil you would just ditch the reference to the previously assigned value (object). Therefore, if you would be calling

self.variable = @"test";
// wrong, do not do this in this case
variable = nil;

you would be be generating a memory leak because the @"test" object that was assigned to variable and retained through its accessor is never going to be released. Why's that? Because the setter (setVariable:) never gets called to know to release the previously held value.

For the sake of example, here's what getVariable looks like:

- (void)getVariable {
    // variable is the class member
    return variable;
}

Let me know if you have further questions.


Yes. self.instanceVar accesses the value through the property.

Although it is not necessarily the synthesized property. You can write your own get and set methods that can be called.

0

精彩评论

暂无评论...
验证码 换一张
取 消