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.