What does "@private" mean in Objective-C?

54,963

Solution 1

It's a visibility modifier—it means that instance variables declared as @private can only be accessed by instances of the same class. Private members cannot be accessed by subclasses or other classes.

For example:

@interface MyClass : NSObject
{
    @private
    int someVar;  // Can only be accessed by instances of MyClass

    @public
    int aPublicVar;  // Can be accessed by any object
}
@end

Also, to clarify, methods are always public in Objective-C. There are ways of "hiding" method declarations, though—see this question for more information.

Solution 2

As htw said, it's a visibility modifier. @private means that the ivar (instance variable) can only be accessed directly from within an instance of that same class. However, that may not mean much to you, so let me give you an example. We'll use the init methods of the classes as examples, for simplicity's sake. I'll comment inline to point out items of interest.

@interface MyFirstClass : NSObject
{
    @public
    int publicNumber;

    @protected  // Protected is the default
    char protectedLetter;

    @private
    BOOL privateBool;
}
@end

@implementation MyFirstClass
- (id)init {
    if (self = [super init]) {
        publicNumber = 3;
        protectedLetter = 'Q';
        privateBool = NO;
    }
    return self;
}
@end

@interface MySecondClass : MyFirstClass  // Note the inheritance
{
    @private
    double secondClassCitizen;
}
@end

@implementation MySecondClass
- (id)init {
    if (self = [super init]) {
        // We can access publicNumber because it's public;
        // ANYONE can access it.
        publicNumber = 5;

        // We can access protectedLetter because it's protected
        // and it is declared by a superclass; @protected variables
        // are available to subclasses.
        protectedLetter = 'z';

        // We can't access privateBool because it's private;
        // only methods of the class that declared privateBool
        // can use it
        privateBool = NO;  // COMPILER ERROR HERE

        // We can access secondClassCitizen directly because we 
        // declared it; even though it's private, we can get it.
        secondClassCitizen = 5.2;  
    }
    return self;
}

@interface SomeOtherClass : NSObject
{
    MySecondClass *other;
}
@end

@implementation SomeOtherClass
- (id)init {
    if (self = [super init]) {
        other = [[MySecondClass alloc] init];

        // Neither MyFirstClass nor MySecondClass provided any 
        // accessor methods, so if we're going to access any ivars
        // we'll have to do it directly, like this:
        other->publicNumber = 42;

        // If we try to use direct access on any other ivars,
        // the compiler won't let us
        other->protectedLetter = 'M';     // COMPILER ERROR HERE
        other->privateBool = YES;         // COMPILER ERROR HERE
        other->secondClassCitizen = 1.2;  // COMPILER ERROR HERE
    }
    return self;
}

So to answer your question, @private protects ivars from access by an instance of any other class. Note that two instances of MyFirstClass could access all of each other's ivars directly; it is assumed that since the programmer has complete control over this class directly, he will use this ability wisely.

Solution 3

It important to understand what it means when somebody says that you can't access a @private instance variable. The real story is that the compiler will give you an error if you attempt to access these variables in your source code. In previous versions of GCC and XCode, you would just get a warning instead of an error.

Either way, at run time, all bets are off. These @private and @protected ivars can be accessed by an object of any class. These visibility modifiers just make it difficult to compile the source code into machine code that violates the intent of the visibility modifiers.

Do not rely on ivar visibility modifiers for security! They provide none at all. They are strictly for compile-time enforcement of the class-builder's wishes.

Share:
54,963

Related videos on Youtube

Jeff Wolski
Author by

Jeff Wolski

Software developer and college instructor with over 23 years experience, including 12 years on the iOS platform. @jeffwolski

Updated on March 16, 2020

Comments

  • Jeff Wolski
    Jeff Wolski over 4 years

    What does @private mean in Objective-C?

  • Stefan
    Stefan about 15 years
    It should be mentioned that it's uncommon to use @public, @proteced and @private in Objective-C. The prefered approach is to always use accessors.
  • Greg Maletic
    Greg Maletic over 13 years
    @Georg, but how do you enforce the use of accessors unless you mark your ivars with restricted visibility?
  • Stefan
    Stefan over 13 years
    @Greg: ivars are by default protected.
  • dawg
    dawg about 13 years
    @Georg Schölly: Since xcode 4.x+ automatically puts @private in the template for an object, it is not so uncommon anymore.
  • chunkyguy
    chunkyguy about 13 years
    @Georg I think @private, @protected can be used for cases where inheritance is involved, haven't used it personally though :)
  • fiacobelli
    fiacobelli over 10 years
    I am trying this in XCode and getting "Illegal interface qualifier" on @public,@protected and @private
  • fiacobelli
    fiacobelli over 10 years
    oops, for all that's worth and whoever this can help, you MUST have { and } around the @private,@public and @protected modifiers. So, if you mix private access with, say @property, the variables that are private should be declared inside its own block of { } and the @property should stay outside of it.
  • BJ Homer
    BJ Homer over 10 years
    It should be noted that these days, there is very little reason to put instance variables in the public header. They can be placed directly on the @implementation block. And once you do that, they're effectively private no matter the visibility modifiers, as they're not even visible to anyone outside that file.
  • John Henckel
    John Henckel about 10 years
    What about instance variables that are in the braces after the @implementation? Are they always private?
  • gnasher729
    gnasher729 about 10 years
    I know it's old... But it's not a visibility modifier. It's an access modifier. It's a more important distinction in C++, but it's a distinction in Objective-C as well. The variable is visible to the compiler. The compiler just doesn't let you access it.