Site Search
Homepage of Otaku No Zoku
Complete Archives of Otaku No Zoku
About Otaku No Zoku
Subscribe to Otaku No Zoku
Bookmark Otaku No Zoku

Objective-C Access To Instance Variables :

Instance variables belonging to an Objective-C 2.0 class are declared protected by default, unlike regular C++ or even C# whereby all declared member variables are private by default. This always confuses C++/C# programmers who are new to Objective-C so if you are familiar with either of those two languages, be aware of this point.

Protection Levels Of Instance Variables

There are four distinct protection levels in Objective-C 2.0 for instance variables, along with four compiler directives that aptly describe what each protection level does, these are:

Protection Level

Compiler Directive

Description

private

@private

The instance variable is accessible only within the class that declares it.

protected

@protected

The instance variables is accessible within the class that declares it and any subclasses that inherit it. This is the default protection method for all instance variables declared in Objective-C 2.0.

public

@public

The instance variable is accessible from any other class or function.

package

@package

The instance variable is accessible from any other class or function inside of the package, i.e. it is treated as though it were declared public, but outside of the package it is treated as private. This is actually useful for instance variables of classes that are declared in libraries, SDK’s and Frameworks.

The @package directive is only applicable to 64-bit operating systems.

A protected instance variable, the default protection level in Objective-C 2.0, can only be accessed by the class that declared them and any class that inherits from the declaring class. Other classes and functions that are not part of the declaring class cannot access a protected instance variable unless a lesser protected accessor method is defined, e.g. you declare your instance variable as protected but the accessor is public, which is a common scenario.

Explicitly Protected vs Implicitly Protected

Because protected is the default protection level of all instance variables, you can declare a protected instance variable either implicitly or explicitly.

The code for an implicit declaration of a protected instance variable is:

@interface Player : NSObject
{
    // This is a protected instance variable that tracks the player’s experience points.
    int m_playerExperience;
}

Which simply declares an integer, which in Objective-C 2.0, is protected by default.

To explicitly declare a protected instance variable, you make use of the @protected compiler directive. So changing the above implicit protected instance variable example to an explicit protected instance variable example would be:

@interface Player : NSObject
{
@protected
    // This is a protected instance variable that tracks the player’s experience points.
    int m_playerExperience;

}

What’s the difference?

Syntactically you’ve just added the extra compiler directive and a little more typing. In terms of code generation, absolutely nothing has changed. The first example will generate the exact same assembler code from the compiler as the second example.

It generally is always good practice to explicitly declare the protection level of your instance variables, even if you know them to be marked protected as default.

Why?

Because someone coming after you, a less experienced programmer perhaps, may not know that Objective-C declares instance variables to be protected by default. But there is also another reason, if you change you code around, perhaps adding in extra instance variables, for example:

@interface Player : NSObject
{
@private
    // This is a private instance variable that tracks the player’s level.
    int m_playerLevel;

    // This is a protected instance variable that tracks the player’s experience points.
    int m_playerExperience;
}

You have correctly declared your player’s level as a private instance variable inaccessible to all sub-classes or external functions, however, you have incorrectly declared your player’s experience as private too, even though it is meant to be protected. In this case, you’d get a compiler error or warning depending on how you access the variable but if you had declared m_playerLevel as @public, you would receive no warning and have introduced a potentially dangerous bug in to your code. This is a trivial example of the usage, but it doesn’t hurt to be explicit, and it can save you a lot of head scratching and many hours of bug hunting in the long run.

Any instance variable protection level directive used in your code, e.g. @private, applies to all instance variables that are listed after it, it stops applying either when a new protection level compiler directive is used, such as @public, or the end of the list of instance variables is reached.

Instance Variable Class Scope

Any instance variable declared in a class is by default within the scope of the class itself, there is no way (that I know of) to correctly* hide an instance variable from the declaring class.

A class will have access to instance variables of any class it inherits from so long as those instance variables were not declared private. To limit the ability of a class to alter instance variables of parent classes it is inheriting from, you use the @private compiler directive. Instance variables marked with the @private compiler directive are only accessible through public accessor methods, if they are available.

Other classes and functions will have access to instance variables if you declare them as public using the @public compiler directive. This means that any class or function, regardless of where it resides in your application can manipulate the public instance variables of a class. Occasionally this is useful, but you should be wary of declaring instance variables as public as it tends to break the data encapsulation of object oriented programming, it’s often better to declare an instance variable as protected (or even private) and then create an accessor method that is public. This lets you change the underlying data type or storage mechanism without breaking any assumptions other programmers have made about your code.

* Yeah, okay, screwing with the program’s data tables, altering compiler output, or otherwise monkeying around in the guts of the generated code is a possible way of doing this, but seriously, if you’re doing that you’re probably trying to be clever rather than being productive.

Liked This Post?

Subscribe to the RSS feed or follow me on Twitter to stay up to date!