Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using @property and @synthesize with ivar implicit creation

Ok, so lately I got this presumable bad habit of declaring my class properties with @property create getters and setters with @synthesize and simply use them anywhere I need them as self.name without having a reference to the inner ivar (let @synthesize do its work)

Now, of course this doesn't allow me to access the inner ivar (eg. name_) but from what I've coded so far, I didn't really need it. For read-only properties I don't use @synthesize but implement the getter myself.

Everything seems fine, but somehow I've got the feeling that this is not right because all the open source libraries I've had a look over, also declared the ivar and used it throughout the code. @property + @synthesize and no ivar its definitely the lazy choice, but what are the drawbacks? Can someone give me some advice?

Also, I've read that, as a general advice, it's OK to use self.propertyName anywhere in your class code except the dealloc and init methods. But as long as you make sure the object is initialize:

-(id) init
{
    if( (self=[super init] )) {

    }
    return self;
}

and you remove all key-value observers before calling [super dealloc] everything should be fine. Right?

like image 652
Rad'Val Avatar asked Aug 02 '11 12:08

Rad'Val


2 Answers

well the @synthesize will create the inner ivar with the same name as the property:

@synthesize name;

- (void) dealloc {
   [name release], name  = nil;
   [super dealloc]
}

Or give the inner ivar an other name:

@synthesize name = _name;

- (void) dealloc {
   [_name release], _name  = nil;
   [super dealloc]
}

I use the self.name in the init but not in the dealloc and seems to work great.

like image 200
rckoenes Avatar answered Nov 14 '22 18:11

rckoenes


It comes down to which version of the Objective-c runtime you are building for: Modern or Legacy.

  • The Modern version supports "instance variable synthesis for declared properties". ie. there is no need for you to define an instance variable for each @property. The runtime will take care of creating one for you. By default the ivar will be named the same as the @property. You can change the ivar name by using the format @synthesize propertyName = iVarName;

  • The Legacy version does not support ivar synthesis and therefore you must define an ivar for storage of your @property.

iPhone applications and 64-bit programs on Mac OS X v10.5 and later use the modern version of the runtime. You should assume that every other platform uses the legacy version.

What are the drawbacks? Well, the biggest one is portability - By not defining the ivars your code can run on fewer platforms e.g. it won't work on OSX 10.4. You also lose some control/flexibility & might inadvertently run into name collisions with sub- & super- classes.

It's important to remember that you should deallocate properties that you have synthesized with @synthesize. Properties are not automatically released - you should release any synthesized property that is not marked assign (don't release any properties marked assign).

N.B. For extra credit you can tidy up your read-only properties. There's little reason to write your own accessor and not use @synthesize. Simply define your property as read-only & optionally what to call the getter @property(getter=isIntReadOnlyGetter, readonly)

like image 37
tdbit Avatar answered Nov 14 '22 17:11

tdbit