What does @private mean in Objective-C?
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.
What does the @package directive do in Objective-C?
@package
is similar to internal
for .NET. It means the member is accessible only from the framework in which it is defined.
Note: In 32-bit it acts like @public
.
Is this a new way to define private instance variables in Objective-C?
It's for real, it's the new way,* it's great, and, yes, it's in the docs. The Objective-C Programming Language, which is as close as we get to having an actual spec for the language, has the following to say:
The definition of a class is structured very much like its declaration. It begins with an
@implementation
directive and ends with the@end
directive. In addition, the class may declare instance variables in braces after the@implementation
directive:
@implementation ClassName
{
// Instance variable declarations.
}
// Method definitions.
@end
There's also a historical note a little ways back from that link, addressing the fact that we used to have to declare ivars in the interface block:
Historically, the interface required declarations of a class’s instance variables, the data structures that are part of each instance of the class. ... Instance variables represent an implementation detail, and should typically not be accessed outside of the class itself. Moreover, you can declare them in the implementation block or synthesize them using declared properties. Typically you should not, therefore, declare instance variables in the public interface and so you should omit the braces.
For the question of privacy, yes, these variables are truly private -- they act like ivars declared in the interface with the @private
directive. This means that subclasses can't access them, by default. Their visibility can be changed, however, using either @protected
or (if necessary for some bizarre reason) @public
:
@interface Stuper : NSObject
@end
@implementation Stuper
{
@protected
NSString * sangfroid;
}
@end
@interface Stub : Stuper
- (void)setSangfroid: (NSString *)newSangfroid;
@end
@implementation Stub
- (void)setSangfroid: (NSString *)newSangfroid {
sangfroid = [newSangfroid copy];
}
*You have to use clang > 3.0, I believe, so that's just a few months ago as of this posting. GCC won't do it.
Private and protected methods in Objective-C
There are three issues:
Hiding from compiler.
That is, making it impossible for someone else to #import something and see your method declarations. For that, put your private API into a separate header file, mark that header's role as "Private" in Xcode, and then import it in your project where you need access to said private API.
Use a category or class extension to declare the additional methods.
Preventing collisions
If you are implementing lots of internal goop, do so with a common prefix or something that makes a collision with Apple provided (or third party) provided methods exceedingly unlikely. This is especially critical for categories and not nearly as critical for your leaf node subclasses of existing classes.
Post the link for the site suggesting leading underscores, as they are wrong, wrong, wrong. Leading underscores are used by the system to mark private API and you can run into collisions easily enough.
Hiding from the runtime.
Don't bother. It just makes debugging / crash analysis harder and anyone determined enough to muck around at the runtime will be able to hack your app anyway.
How do I use this private API?
Have you tried calling performSelector? That is usually the trick to call private methods. Remember all that makes a method private in Objective-C is the fact that it is not advertised in the h file. But if you send a message to an object and the object can respond to that message it will, regardless of what's in the header file.
Accessing hidden private class in Objective-C
The attribute keyword is simply a message to the compiler, and has nothing to do with the runtime. Using ((visibility("xxx")) only serves to tell the compiler if the given declaration should be "visible" or usable by clients in some other package. visibility("hidden") just means that, despite the public declaration, make this thing invisible to external packages, so that they will not be able to use it. Compiling will fail if you attempt to use this class or method.
If you don't see this class being used in a recursive description, it is likely that this class is no longer used; it certainly isn't because of the attribute statement.
Related Topics
Xcode 6 - Launch Simulator from Command Line
Document Directory Path of Xcode Device Simulator
How to Add Images for Different Screen Size from Assets.Xcassets in Xcode 8
Switch Cameras with Avcapturesession
Differencebetween a Property and a Variable in Swift
Xcode Myprojectname-Bridging-Header.H Does Not Exist
Handling Private Frameworks in Xcode ≥ 7.3
App Rejected Because of Advertisingidentifier in Facebook Sdk and Flurry Sdk
Difference Between Dispatchqueue.Main.Async and Dispatchqueue.Main.Sync
Xcode 8 Build Crash on iOS 9.2 and Below
Should I Declare Variables in Interface or Using Property in Objective-C Arc
Optional Binding with Try? and As? Still Produces an Optional Type
"Reading from Public Effective User Settings" in iOS 10
How I Get Whatsapp Abid to Compose a Message to a Specific User in iOS