Take the 2-minute tour ×

In implementing an interface it seems the common method in tutorials and literature is to declare an ivar and then set the @property then @synthesize.

@interface MyClass : NSObject {
NSString *myString;

@property (nonatomic, retain) NSString *myString;

However, omitting the explicit declaration and just putting @property has the same effect.

@interface MyClass: NSObject {

@property (nonatomic, retain) NSString *myString;

So how come most people use @property and an explicit declaration? Is it bad form not to?

share|improve this question
+1 great question –  Dave DeLong Apr 5 '11 at 18:18
Tradition!!!!!! –  Hot Licks Nov 28 '12 at 16:40

4 Answers 4

up vote 14 down vote accepted

It used to be necessary. There are two different versions of the Objective-C runtime: a 32-bit-only "legacy" runtime (the old one) and a 32/64-bit runtime (the new 32-bit runtime is only used on iOS devices and for the iOS simulator).

I think the only place this is still necessary is when you're running the app in 32-bit mode (either 10.5 or 10.6). Everywhere else (64-bit Leopard, 64-bit Snow Leopard, Lion, iOS) uses the newer runtime that has "automatic ivar synthesis", and the resulting ivars are referred to as "synthesized ivars".

share|improve this answer
I haven't done much iPhone programming lately. Do they work on the simulator now? I'm pretty sure they didn't use to. –  Chuck Apr 5 '11 at 17:29
@Chuck I think you're right. I think the simulator still uses the 32-bit legacy runtime (though that might have changed recently; I'm not sure). –  Dave DeLong Apr 5 '11 at 17:31
IIRC synthesized ivars work in the simulator now, if my memory of the WWDC videos serves me correctly… –  Wevah Apr 5 '11 at 17:35
@Wevah just checked, and you're correct. The simulator got the new runtime about a year ago (your memory of WWDC is correct). –  Dave DeLong Apr 5 '11 at 17:54
Yep! For your own apps and libraries, if your user-base is of the right sort, I'd suggest using the latest runtime features whenever possible. I'm always annoyed at new open-source libraries that are full of archaisms like that; I understand why (backward compatibility), but it just makes me a little unhappy… :) –  Jonathan Sterling Apr 5 '11 at 18:00

Some platforms support synthesized instance variables, some don't. Explicitly declaring instance variables makes your code valid in more places, and it used to be outright necessary until very recently, so people still do it. In a few years, they probably won't anymore.

share|improve this answer

Using modern versions of Xcode (anything about 4.2 or later) there is no reason to declare a iVar in your header, EVER. Anything publicly accessible should be declared as a property.

Many forget that Objective C objects are actually pointers to C structs. As such, any iVar that is declared in your header can be accessed directly, by passing your getters and setters, using myObject->myPublicIVar. Especially in non-ARC code, that is extremely dangerous. The @private directive prevents the use the -> operator to access iVars, but still clutters the header file. There's no point in @private when there are better ways.

Anything private should be declared within your .m file. Often, this requires a class extension, like this:

// The .h file
@interface Foo : NSObject
@property (nonatomic, strong) NSString *myPublicString;

// The .m file
@interface Foo ()
@property (nonatomic, strong) NSString *myPrivateString;

@implementation Foo {
    NSString *myPrivateIVar;

// Xcode 4.5 or later will not require these @synthesize
@synthesize myPublicString = _myPublicString;
@synthesize myPrivateString = _myPrivateString;


An implementation like this provides a public property backed by an iVar, a private property backed by an iVar, and a private independent iVar. I've included the @synthesize directives, but they are not necessary using modern tools.

share|improve this answer

The @property only implements the accessor methods, the instance variable itself has to exist. Try ignoring the ivars and it will fail on runtime, if not on compile time.

share|improve this answer
Only on some platforms. –  Chuck Apr 5 '11 at 17:24
-1 it will only fail on 32 bit platforms using the legacy runtime. –  Dave DeLong Apr 5 '11 at 17:25

Your Answer


