Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between ivars and properties in Objective-C

What is the semantic difference between these 3 ways of using ivars and properties in Objective-C?

1.

@class MyOtherObject;  @interface MyObject { } @property (nonatomic, retain) MyOtherObject *otherObj; 

2.

#import "MyOtherObject.h" @interface MyObject {     MyOtherObject *otherObj; } @property (nonatomic, retain) MyOtherObject *otherObj; 

3.

#import "MyOtherObject.h" @interface MyObject {     MyOtherObject *otherObj; } 
like image 848
ennuikiller Avatar asked Nov 13 '10 13:11

ennuikiller


People also ask

What is Ivars Objective-C?

Accessing an ivar through a getter/setting involves an Objective-C method call, which is much slower (at least 3-4 times) than a "normal" C function call and even a normal C function call would already be multiple times slower than accessing a struct member.

What is a property in Objective-C?

Objective-C properties offer a way to define the information that a class is intended to encapsulate. As you saw in Properties Control Access to an Object's Values, property declarations are included in the interface for a class, like this: @interface XYZPerson : NSObject.

What is synthesize in Objective-C?

@synthesize tells the compiler to take care of the accessor methods creation i.e it will generate the methods based on property description. It will also generate an instance variable to be used which you can specify as above, as a convention it starts with _(underscore)+propertyName.


1 Answers

Number 1 differs from the other two by forward declaring the MyOtherObject class to minimize the amount of code seen by the compiler and linker and also potentially avoid circular references. If you do it this way remember to put the #import into the .m file.

By declaring an @property, (and matching @synthesize in the .m) file, you auto-generate accessor methods with the memory semantics handled how you specify. The rule of thumb for most objects is Retain, but NSStrings, for instance should use Copy. Whereas Singletons and Delegates should usually use Assign. Hand-writing accessors is tedious and error-prone so this saves a lot of typing and dumb bugs.

Also, declaring a synthesized property lets you call an accessor method using dot notation like this:

self.otherObj = someOtherNewObject; // set it   MyOtherObject *thingee = self.otherObj; // get it  

Instead of the normal, message-passing way:

[self setOtherObject:someOtherNewObject]; // set it MyOtherObject *thingee = [self otherObj]; // get it  

Behind the scenes you're really calling a method that looks like this:

- (void) setOtherObj:(MyOtherObject *)anOtherObject {      if (otherObject == anOtherObject) {         return;       }      MyOtherObject *oldOtherObject = otherObject; // keep a reference to the old value for a second     otherObject = [anOtherObject retain]; // put the new value in       [oldOtherObject release]; // let go of the old object } // set it 

…or this

- (MyOtherObject *) otherObject {       return otherObject; } // get it 

Total pain in the butt, right. Now do that for every ivar in the class. If you don't do it exactly right, you get a memory leak. Best to just let the compiler do the work.

I see that Number 1 doesn't have an ivar. Assuming that's not a typo, it's fine because the @property / @synthesize directives will declare an ivar for you as well, behind the scenes. I believe this is new for Mac OS X - Snow Leopard and iOS4.

Number 3 does not have those accessors generated so you have to write them yourself. If you want your accessor methods to have side effects, you do your standard memory management dance, as shown above, then do whatever side work you need to, inside the accessor method. If you synthesize a property as well as write your own, then your version has priority.

Did I cover everything?

like image 135
willc2 Avatar answered Sep 22 '22 00:09

willc2