views:

8480

answers:

2

What does @private mean in Objective-C?

+48  A: 

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.

htw
@daniel, you're entitled to your opinion but it's only *your* opinion, others may not share it. I'm actually happy to see even simple lazy questions show up on SO so it can become the repository of choice for *all* programming questions. And, if a question is asked, it *should* be answered. The way of handling questions you don't like is to downvote or vote to close, then vote to delete if you're really passionate.
paxdiablo
Pax: you have a lot more experience with SO and I respect that because of that, you might have a more enlightened view than I do, about how the site should function.But speaking as one of the "experts" who might chime in and provide answers to the real hard questions, I'm turned off when the site becomes tainted by "lazy" questions. I'm certainly willing to let the site bcome what it will, but questions like this will drive away people like myself who have no patience for vague, lazy inquiries.
danielpunkass
@daniel: I don't really see a problem with lazy questions. If you don't like the question, down vote and move on.
cdmckay
Don't forget @protected for ivars which can only be accessed by other instances of MyClass, or one of its subclasses.
Mike Abdullah
@Mike: I was thinking about adding that, especially since instance variables default to @protected, but I felt that would over-complicate the answer, which was specifically about @private.
htw
@daniel, I see it as a (tricky) balancing act. I'd like to see SO used both for the experienced and newcomers so I don't tend to dislike questions that have a specific technical answer (such as this one) no matter how simple they seem. And my experience here doesn't mean much really - anyone above 10k has the same power. Whether they have the same *goals* for SO, I have no idea. I've actually mellowed a bit since my early days here. I used to be much harsher (I'd still like to beat into an early grave every author of a question with the word "favorite" in it but that's another matter :-)
paxdiablo
Does @private, @public and @protected work with methods? Can someone post some example code, I get compile errors.
rjstelling
@rjstelling: No, methods are always public in Objective-C. As for the issue of private methods in Objective-C, see this question: http://stackoverflow.com/questions/172598/best-way-to-define-private-methods-for-a-class-in-objective-c
htw
@daniel go and found eliteststackoverflow.com if you like.
Max Howell
@Max - I am sorry I offended you.
danielpunkass
+17  A: 

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 direct instances of the class that declared it
        // 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.

BJ Homer
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.
Georg
BJ, this is the most succinct and helpful response to this question I've seen. Very well put.
MikeyWard