Learn Objective-C: Variable Scope

You can control a variable’s scope, or from where in your program it is accessible.

Language Directives

Up until now, we have seen that instance methods can access instance variables—a class can access its own variables (makes sense, and that’ll never change). More interesting is that subclasses can also access those same instance variables—that’s the default option. But you can change this:

  • @protected: The default case, the variable can be accessed by methods in the defining class and all subclasses.
  • @private: The instance variable can be accessed by instance methods in the defining class, but subclasses can not.
  • @public: Any class can access the variable, provided that the header of the defining class is imported, as usual.
  • @package: Any class within the same framework can access the variable. For example, a @package variable defined in NSString could be accessed by any other class in the Foundation framework, but nowhere else.

These directives act as switches, signifying that all the variables that follow are to be of that scope until another directive or a closing brace is encountered.

  1. @interface Printer : NSObject
  2. {
  3.      @private
  4.           NSInteger jobPageCount;
  5.           double tonerLevelPercentage;
  6.      @protected
  7.           NSString *brand;
  8. }
  9. // …
  10. @end

The @public directive allows the variable to be accessed by other methods outside of that class. Making instance variables public is considered a poor programming practice because it defeats the purpose of data encapsulation (a class hiding its instance variables).

External Global Variables

If you declare a variable, such as int globalVar = 0; outside any method or block, it is known as a global variable—it is accessible to any method or block in that file, even if you declare multiple classes (as we did in the beginning) in one file.

As a matter of fact, declaring the variable as such makes it accessible to any file that #imports it as any other variable—in this sense, it is a global variable.

To declare an external variable specifically (such as within a block, to be used in other blocks), you can use the extern keyword:

extern int extVar;

As a matter of fact, you should not assign extVar a value. The extern keyword tells the compiler that a variable should be external. The keyword is a declaration, not a definition.

Note that you can only define a global variable once, but you can specify any variable as being extern any number of times.

Static Variables

At times there may be a need to declare a variable as global but not external—that is, anything in the file can access the variable, but it cannot be accessed in another file. This is where you would use the static keyword.

Placing a line such as static int allocCounter = 0; outside any method in a file makes such a static variable. One practical application is that you can use this as a “class variable” of sorts—in this case, you would be able to use this variable to keep track of how many instances of a class were allocated, perhaps by overriding the -init method:

  1. // Fraction.m
  2. static int instancesCounter = 0;
  4. - (id)init {
  5.   extern int instancesCounter;
  6.   instancesCounter++;
  7.   return [super init];
  8. }

This post is part of the Learn Objective-C in 24 Days course.

Author: Feifan Zhou