1

Possible Duplicate:
Difference between self.ivar and ivar?

In Objective-C, what's the difference between [self setVariable: newStuff] and variable = newStuff?

When you have a class with a variable

@property (nonatomic) NSInteger num;

and you want to change the variable, typically you can do

[self setNum: newNum]

but you can also do

num = newNum

I know if you declare the variable readOnly, you can't use the first method to change it, but what's the concept behind it? Is it just because the second method with the setter can be called outside of its own class? Like if the class's instance was called 'sample'.

[sample setNum: newNum]

but then if you are changing the variable inside the class, either way is fine?

Community
  • 1
  • 1

3 Answers3

2

In Objective-C, what's the difference between [self setVariable: newStuff] and variable = newStuff?

To be absolutely pedantic, one of them assigns the variable property the value in newStuff, whereas the other one assigns the value of newStuff to the iVar variable, but what I think you had in mind was a comparison between [self setVariable: newStuff] and self.variable = newStuff. In that case, nothing is different, the compiler will expand case 2 out to case 1.

I know if you declare the variable readOnly, you can't use the first method to change it, but what's the concept behind it? Is it just because the second method with the setter can be called outside of its own class? Like if the class's instance was called 'sample'.

readonly variables are important in cases where certain properties are private to the implementation of a class, but should be visible to other classes.

For example, if I were writing a Stack, I might want to expose the count of the number of items on the stack, but it would be a very bad idea for other classes to be able to write to the count variable. If I weren't smart and were using something like a count variable, I would want to be able to adjust the count of the semaphore internally (meaning you need it to be internally readwrite), so I declare a visibly readonly property so other classes can get it, but declare it internally readwrite so I can modify it:

//.h
@interface CFExampleStack : NSObject 

@property (nonatomic, assign, readonly) int count; //readonly

@end

//.m
@interface CFExampleStack ()

@property (nonatomic, assign) int count; //readwrite

@end
CodaFi
  • 43,043
  • 8
  • 107
  • 153
  • I don't think OP meant the difference between the two case where... well, there's no difference. He specifically used the term `variable`. –  Dec 25 '12 at 04:40
  • His title is different from his questions. I answered what I saw – CodaFi Dec 25 '12 at 04:41
  • lol, true... hate these questions... –  Dec 25 '12 at 04:44
  • I up-voted the answer because I thought it was a good explanation. I don't know if it was the answer the questioner was looking for! – Jim Merkel Dec 25 '12 at 04:48
1

Is it just because the second method with the setter can be called outside of its own class?

Well, that depends on how your instance variable is declared. By default, instance variables are @protected, i. e. they can be accessed from within the class and its subclasses only. However, if you explicitly declare an ivar as @public, then you can access it outside the class, using the C struct pointer member operator ->:

obj->publicIvar = 42;

However, this is not recommended, since it violates encapsulation.

Furthermore, if you use a custom setter method, then you have the opportunity to do custom actions when a property of an instance is updated. For example, if one changes the backgroundColor property of a UIView, it needs to redraw itself in addition to assigning the new UIColor object to its appropriate ivar, and for that, a custom setter implementation with side effects is needed.

Additionally, there are retained ("strong") and copied properties in case of instance variables that hold object. While writing a setter for a primitive type such as an integer is as simple as

- (void)setFoo:(int)newFoo
{
    _foo = newFoo;
}

then, in contrast, a retained or copied property needs proper memory nanagement calls:

- (void)setBar:(Bar *)newBar
{
    if (_bar != newBar) {
        [_bar release];
        _bar = [newBar retain]; // or copy
    }
}

Without such an implementation, no reference counting would take place, so the assigned object could either be prematurely deallocated or leaked.

1

One more important difference...

Whenever you use self.prop KVC comes into play and you can observe the changes in the object, while _prop bypasses it.

Anoop Vaidya
  • 46,283
  • 15
  • 111
  • 140