I’ve recently updated to Xcode 4.3.2 and found that I can now declare private instance variables inside @implementation block like so:
@interface TestClass : NSObject
@property (nonatomic, copy) NSString *testProp;
@end
@implementation TestClass {
NSString *_testPropStore;
}
- (NSString *)testProp { return _testPropStore; }
- (void)setTestProp:(NSString *)testProp { _testPropStore = [testProp copy]; }
- (id)init {
if (self = [super init]) {
_testPropStore = nil;
}
return self;
}
@end
Notice the NSString *_testPropStore line inside @implementation brace block.
I’ve also tested with the following code:
TestClass *c1 = [[TestClass alloc] init];
TestClass *c2 = [[TestClass alloc] init];
c1.testProp = @"Hello";
c2.testProp = @"World";
NSAssert(c1.testProp == c2.testProp, @"It's working!");
Which seems to work fine. (That is, the app crashes with the “It’s working” message at the NSAssert line.)
So is this a new feature of Objective-C for declaring private instance variables? Since I discovered this by accident, I would love to know if it is just for declaring private instance variables or will there be any side effects that I’m not aware of?
I couldn’t find any relevant document since most questions of such type with the word private just ended up with answers on how to declare them on a private extension category which is different.
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:
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:
For the question of privacy, yes, these variables are truly private — they act like ivars declared in the interface with the
@privatedirective. This means that subclasses can’t access them, by default. Their visibility can be changed, however, using either@protectedor (if necessary for some bizarre reason)@public:*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.