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.
Instance variables are encapsulated by using the private access modifier. Methods can be public or private, but they are usually public.
In Objective-C, instance variables are commonly created with @propertys. An @property is basically an instance variable with a few extra bonus features attached. The biggest addition is that Objective-C will automatically define what's called a setter and a getter for you automatically.
The instance variables are visible for all methods, constructors, and block in the class. Normally, it is recommended to make these variables private (access level). However, visibility for subclasses can be given for these variables with the use of access modifiers. Instance variables have default values.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With