2

What's the difference between declaring a @private ivar in the header file and declaring the same ivar in the class extension without @private? As far as I understand it's the same thing.

Also, can you declare a private property in the header?

2 Answers 2

3

The concept is to declare in the header file only those things (methods, properties, etc) which are public. Declare all private items in the implementation file's class extension.

This provides the class users only information that is available for their use and hides all else. It also make it easier for a user of the class quickly see the functionality available to him. Writing code is all about readability and understandability to the developer.

This way a developer is free to change anything that is not exposed in the header files without making any externally visible changes.

In recent versions of Objective this is finally fully releasable via class extensions.

Sign up to request clarification or add additional context in comments.

6 Comments

Then what is @private for?
Originally all declarations were required tone in the interface file as in several other related languages. Over time Apple modified Objective-C such that the declarations could be separated between the interface and implementation files. @private still works and must remain for backward compatibility. Note: In the early days it was not well understood what should go in a header file by most developers, over time we figured that out. Some languages change to allow separation between the interface and implementation.
Some languages do not even allow an interface file thus thwarting the concept of "Design to the Interface" (I'm looking at you Swifty).
Even in pre-property ObjC, @private was pretty rare, since we learned that you shouldn't mess directly with another object's ivars. So most of us treated all ivars as "private" and used accessors at least from outside the class (and many of us used accessors inside the class). Old-school ObjC was almost entirely "safety through convention" rather than by compiler enforcement.
BTW, it's worth reminding the OP that in modern ObjC it is rare that you should declare an ivar at all. You should just declare properties in almost all cases. (I still use non-property ivars occasionally to manage buffers that are exclusively handed to low-level C interfaces, but even then I shy away from it.)
|
2

What's the difference between declaring a @private ivar in the header file and declaring the same ivar in the class extension without @private?

There are a few differences. In short, variables declared in the header file are visible to subclasses and class categories. Variables declared in the implementation are not.

1) Instance variables declared in a class's main @interface block are available to external class categories or extensions, even if those variables are declared @private. E.g.:

// YourClass.h
@interface YourClass : NSObject {
    @private
    int _yourPrivateIVar; 
}
@end

// MyExtension.m
@implementation YourClass(MyExtension)
- (void)reset { _yourPrivateIVar = 0; } // This is allowed.
@end

Instance variables declared in the implementation are not available to external class categories.

2) A base class and its subclass cannot both declare the same ivar in their @interface, even if both ivars are @private. E.g., this is not allowed:

@interface Base : NSObject
{
    @private
    int _foo;
}
@end

@interface Subclass : Base
{
    @private
    int _foo; // Error: Duplicate member _foo
}
@end

If both ivars are declared in a class extension or implementation block then not only does it compile but it works as expected: both classes have their own separate _foo ivars that do not conflict with one another. On other words, both variables are truly private and separate:

@implementation Base {
    int _foo;
}
@end

@implementation Subclass {
    int _foo;
}
- (void)reset { _foo = 123; } // Does not affect base class's _foo
@end

Note: If the base class and subclass declare a "private" property or method with the same name it will compile without warning or error, but it will fail spectacularly at runtime as both classes unknowingly interfere with each other's private data.

2 Comments

So then what's the difference between declaring in class extension vs declaring in @implementation block?
@AlexCraciun There is no difference in that case.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.