selytch
selytch

Reputation: 535

objective-c instance variables

There was a question couple years back re instance vs class methods. It was illustrated with the code below. I understand for the most part, except why do I need both instance variable "age" and instance method "age"?

Won't getter and setter for instance variable "age" be created with @synthetize?

Static int numberOfPeople = 0;

@interface MNPerson : NSObject {
     int age;  //instance variable
}

+ (int)population; //class method. Returns how many people have been made.
- (id)init; //instance. Constructs object, increments numberOfPeople by one.
- (int)age; //instance. returns the person age
@end

@implementation MNPerson
- (id)init{
    if (self = [super init]){
          numberOfPeople++;
          age = 0;
    }    
    return self;
}

+ (int)population{ 
     return numberOfPeople;
}

- (int)age{
     return age;
}

@end
main.m:

MNPerson *micmoo = [[MNPerson alloc] init];
MNPerson *jon = [[MNPerson alloc] init];
NSLog(@"Age: %d",[micmoo age]);
NSLog(@"%Number Of people: %d",[MNPerson population]);

(Original code from @micmoo)

Upvotes: 1

Views: 287

Answers (2)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 727077

The instance method age is for encapsulation. It lets subclasses override the method, providing a different implementation if they need to. For example, a subclass may want to calculate the age based on the initial date and the current date, rather than storing it. If you use an instance variable, subclasses would have no option to override age; if you add an instance method, then subclasses would be able to provide new implementation.

Another advantage is that you cannot write to age: the users of your class can get the age, but they cannot set it.

Won't getter and setter for instance variable "age" be created with @synthetize?

The @synthesize requires a property declaration, which is missing from the class. Properties are relatively new to the language, which may explain the reason why they are not used in the code that you found.

The current way of doing the same thing is declaring a property instead of an ivar and an accessor, and skipping the @synthesize altogether:

@property (nonatomic, readonly) int age;

You can write to age from inside the class by assigning _age, the backing variable created automatically; the users can read the value by using either [obj age] or obj.age syntax.

Upvotes: 5

jscs
jscs

Reputation: 64022

This code was apparently written prior to the introduction of declared properties and the @sythesize directive, which were introduced with so-called "Objective-C 2.0" at the time of Mac OS X Leopard. A brief introduction is available at The Cacao, which will demonstrate to you what the old way looked like.

Yes, it would be far better to do it the modern way, but in those dark ages, we had to declare every ivar in the class's interface, and to write every setter and getter manually. Every single one, uphill both ways, in the snow, with no boots.

Upvotes: 3

Related Questions