I want to make an instance variable that can\'t be accessed from outside. Is something like that possible in objective-c? I remember Apple has private variables and stuff li
You can define private methods by simply having them only in the @implementation, and not the @interface.
Similarly, you can define private instance variables inside an anonymous block at the start of the @implementation - as you do for public ivars inside the @interface.
See the following example.
@interface EXClass : NSObject
{
uint8_t publicInteger;
float publicFloat;
}
-(void)publicMethod;
@end
@implementation EXClass
{
uint8_t privateInteger;
float privatefloat;
}
-(BOOL)privateMethod {
return FALSE;
}
Remember that objective-C methods are sent as messages at runtime, though (rather than C++'s compile time binding), so respondsToSelector: would still return true and performSelector: would still call the method. The ivars would be fully private.
If you were making a library, though, theoretically no one would know about any methods you didn't declare in the header files.
All iVars in Objective-C are protected by default. If you don't write the accessor methods than other classes won't be able to see the variables.
The two exceptions are categories and subclasses.
You can not make a real private instance variable. Objective-C is a dynamic language and therefore it is possible to access any variable (even @private).
Use it in the implementation block of you .m file. Then it is not visible and block KVC, so that KVC will not work
@implementation ClassName {
// default to @protected
// but the subclasses can't see ivars created in the implementation block
float number;
}
+ (BOOL)accessInstanceVariablesDirectly {
return NO; // no KVC
}
@end
I saw the following usage in a sample app (PaintGL) by Apple
In .m file
@interface MyClass (private)
- (void) privateMethod();
@property(...) myProperty;
@end
Disclaimer: The sample app only has method declarations, I saw the private property declaration in this SO thread
With the new LLVM Compiler available in XCode 4 and later, you can declare @private
variables in default categories inside your implementation (.m) file:
@interface ClassName()
{
@private
// private variables here
}
@end
@implementation ClassName
// you can use private variables here
@end
I find this convenient, as I hate the pollution private variables bring into my header files.
The Apple docs for naming instance variables doesn't explicit warn against using underscore in the name of instance variables like the private method documents do.
Naming Instance Variables and Data Types
I also remember a conversation between Wil Shipley and a few other OS X developers concern the underscores. Because of the way the Obj-C compiler works, if Apple were to add a new instance variable to a class in their frameworks, it would cause all apps using those frameworks to need to be recompiled. As far as pre-existing instance variables, you should get a warning when you step on one.