I\'ve recently updated to Xcode 4.3.2 and found that I can now declare private instance variables inside @implementation
block like so:
@interfa
It's for real, it's the new way,* it's great, and, yes, it's in the docs. The Objective-C Programming Language, which is as close as we get to having an actual spec for the language, has the following to say:
The definition of a class is structured very much like its declaration. It begins with an
@implementation
directive and ends with the@end
directive. In addition, the class may declare instance variables in braces after the@implementation
directive:
@implementation ClassName
{
// Instance variable declarations.
}
// Method definitions.
@end
There's also a historical note a little ways back from that link, addressing the fact that we used to have to declare ivars in the interface block:
Historically, the interface required declarations of a class’s instance variables, the data structures that are part of each instance of the class. ... Instance variables represent an implementation detail, and should typically not be accessed outside of the class itself. Moreover, you can declare them in the implementation block or synthesize them using declared properties. Typically you should not, therefore, declare instance variables in the public interface and so you should omit the braces.
For the question of privacy, yes, these variables are truly private -- they act like ivars declared in the interface with the @private
directive. This means that subclasses can't access them, by default. Their visibility can be changed, however, using either @protected
or (if necessary for some bizarre reason) @public
:
@interface Stuper : NSObject
@end
@implementation Stuper
{
@protected
NSString * sangfroid;
}
@end
@interface Stub : Stuper
- (void)setSangfroid: (NSString *)newSangfroid;
@end
@implementation Stub
- (void)setSangfroid: (NSString *)newSangfroid {
sangfroid = [newSangfroid copy];
}
*You have to use clang > 3.0, I believe, so that's just a few months ago as of this posting. GCC won't do it.
It's pretty new and it's valid as long as any compiler you need supports it.
It's great for minimizing your dependencies -- the includes and forwards may largely be in the implementation file. For this reason, and if all the compilers you use support it, then it's a better place for your ivars than in the @interface
block.
A final caveat is that our current (may.2.2012) debuggers do not support this.