How to create a real private instance variable?

I want to create an instance variable that cannot be accessed from outside. Is this possible in objective-c? I remember that Apple has private variables and the like, but if people know about them, they can use them. Apple calls this the “private API,” but obviously others can access this material if they find out what is there.

Until now, I thought that something like this creates a private instance variable:

@interface MyClass : NSObject { CGFloat weight; } 

No @property, no @synthesize, only the announcement above.

I also know that Apple adds _inFrontOfTheirPrivateInstanceVariables, but they said somewhere that they don't like it when others do it because they can override randomly hidden instance variables in doing so.

What is the trick here?

+51
visibility private objective-c instance-variables
Aug 11 '09 at 19:40
source share
7 answers

You can use the @private keyword inside {} to make all subsequent variable declarations private. The default @protected (which is similar to protected in Java) and usually works well. You will need to specifically declare the variable as @public so that it is directly accessible outside the class.

This Apple documentation contains additional information about the scope and visibility of variables.

There is also a distinction between a “private API” and private variables. In Objective-C, you cannot use private methods - anyone can call any method. There are several ways to create “secret” methods, but this is somewhat beyond the scope of this question. Here are some related SO questions:

  • About private instance variables in Objective-C
  • What does "@private" mean in Objective-C?
  • Is it possible to declare a method as private in Objective-C?
  • Best way to define private methods for a class in Objective-C

As for the lead _ in front of the variables, keep in mind that Apple also reserves this prefix for the "private" methods. The best way to ensure that you avoid problems is to use the usual naming conventions for your own variables and methods. However, if you do not subclass something from Cocoa (other than NSObject), you can be pretty sure that you will not run into problems.

+60
Aug 11 '09 at 19:41
source share
— -

With the new LLVM compiler, available in Xcode 4 and later, you can declare @private variables in the 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 fact that private pollution variables contribute to my header files.

+30
Jun 09 '11 at 15:00
source share

You can define private methods just by using them only in @implementation and not in @interface.

Similarly, you can define private instance variables inside an anonymous block at the beginning of @implementation - just like for public ivars inside @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, although (instead of binding C ++ compile time), therefore responsesToSelector: will still return true and make a choice: it will still call the method. Ivarians will be completely closed.

If you were creating a library, theoretically no one would know about any methods that you did not declare in the header files.

+9
Aug 19 '12 at 19:27
source share

All iVars in Objective-C are protected by default. If you do not write access methods than other classes, they will not be able to see variables.

Two exceptions are categories and subclasses.

+3
Aug 11 '09 at 19:45
source share

Apple docs for naming instance variables do not explicitly warn against using underscores in instance variable names, such as private method documents.

Instance Variable Names and Data Types

I also remember that the conversation between Wil Shipley and several other OS X developers is about underlining. Due to the way the Obj-C compiler works, if Apple were to add a new instance variable to the class within its framework, this would force all applications using these frameworks to recompile. As for pre-existing instance variables, you should get a warning when you click on it.

+2
Aug 11 '09 at 20:49
source share

I saw the following use in an example application (PaintGL) from Apple

In the .m file

 @interface MyClass (private) - (void) privateMethod(); @property(...) myProperty; @end 

Disclaimer: The sample application has only method declarations, I saw a private property declaration in this SO stream

+2
Mar 05 '13 at 18:26
source share

You may not create a real private instance variable. Objective-C is a dynamic language, and therefore you can access any variable (even @private).

My best approach:

Use it in the implementation block of your .m file. Then it is not visible and blocks KVC, so 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 
+1
Sep 06 '13 at 9:30
source share



All Articles