Objective C: Why do we declare ivars in the .h member area if @property seems to do it automatically?
Asked Answered
D

4

15

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;
@end

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

@interface MyClass: NSObject {
}

@property (nonatomic, retain) NSString *myString;
@end

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

Disposure answered 5/4, 2011 at 17:13 Comment(0)
T
15

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".

Troxler answered 5/4, 2011 at 17:27 Comment(6)
I haven't done much iPhone programming lately. Do they work on the simulator now? I'm pretty sure they didn't use to.Rusel
@Rusel 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).Troxler
IIRC synthesized ivars work in the simulator now, if my memory of the WWDC videos serves me correctly…Cryptology
@Cryptology just checked, and you're correct. The simulator got the new runtime about a year ago (your memory of WWDC is correct).Troxler
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… :)Simmon
This is completely untrue. The necessity to manually declare an iVar to back a property is a compiler feature, not a runtime feature. Developing with Xcode 4.5 or later, even for iOS 3.2, will not require declaration of iVars.Intercommunion
R
2

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.

Rusel answered 5/4, 2011 at 17:26 Comment(0)
I
1

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;
@end


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

@implementation Foo {
    NSString *myPrivateIVar;
}

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

@end

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.

Intercommunion answered 19/10, 2013 at 19:22 Comment(0)
D
-3

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.

Demodulate answered 5/4, 2011 at 17:17 Comment(1)
-1 it will only fail on 32 bit platforms using the legacy runtime.Troxler

© 2022 - 2024 — McMap. All rights reserved.