Properties

Reading a writing variables can be complex. For example, setting an instance variable might look like this,

The definition is this,

    Class * myObject;

and the code is this.

    myObject = value;

Several things deserve attention:

  • Does myObject already contain a pointer to another value? If so, should you release that object?
  • Is it possible that myObject is the same object as value? (i.e. the pointers are the same.)
  • Do you want to use the pointer to value, or do you want to make a copy of value and use the pointer to this new object?
  • If this object can be reached by code in another thread, do you want to protect it against multiple access?
  • Should the variable be read only?

Declaring an instance variable as a property will make it available to the rest of the program, and the declaration allows you to set limits on the access. For example, you can declare it readonly and prevent any outside code from changing it.

  • nonatomic. By default, access to the property is protected by guards that prevent multiple threads from interfering with each other. Normally this is not a problem, and one would specify nonatomic because it is faster.
  • retain increases the retain count and asserts ownership of the object.
  • copy creates a new variable with a new pointer and a retain count of 1. Copying is done by a method defined for each class. See the NSCopying protocol.
  • assign just assigns, and is the default. You can use only one of retain/copy/assign.
  • readonly disallows writing to the variable. The default is readwrite.

Perhaps the most common property declaration is,

    @property (nonatomic, retain) Class * myObject;

The effect of a property declaration is to create two method declarations,

    -(Class*) myObject;
    -(void) setMyObject:(Class*) newValue;

These do not appear in the source code, but they are seen by the compiler. The first is the "getter" method. It has the name of the variable, unaltered. The second is the "setter", whose method name begins with "set" followed by the variable name with the first letter in upper case.

If the declaration is "readonly" only the getter will be generated.

No code is created, these are simply promises that code will be generated or written. The user can write the corresponding methods, but that is usually not done. Rather, the compiler will generate the methods when @synthesize is used. It is placed inside the implementation file.

    @synthesize myObject;

This creates the code for the two accessor methods, and that code follows the rules given in the attributes of the @property declaration. As with @property you don't see this code, but the compiler does.

Given a declaration like this,

    @property (nonatomic, retain) Class * myObject;

The method "setMyObject" will be created. It will use nonatomic access, that is, no protection against multiple threads, and it will release the previous content of myObject and retain the new value. The code would effectively be,

    -(void)setMyObject:(Class *)newObj {
      if (myObject != newObj) {
       [myObject release];
       myObject = [newObj retain];
       }
     }

A declaration like this,

    @property (nonatomic, copy) Class * myObject;

would create something like this,

    -(void)setMyObject:(Class *)newObj {
      Class * temp = [newObj copy];
      [myObject release];
      myObject = temp;
     }


If a variable is read only, how does it acquire its initial value? Objective C allows plain old C assign statements. Within a class method a variable can be addressed as,

       var = value;
       self->var = value;

       [self setVar:value];
       self.var = value;


The first two of these are C language access. They deal with the variable directly and do not use the accessors. They can give the variable an initial value and change it at any time. They are not bound by the attributes in the property declaration.

The latter two lines use the setter accessor. Since that method does not exist for a readonly variable they will fail because the compiler will be unable to link to the method.

In these examples we have identified a property with a specific instance variable. If you write your own accessors, you can make properties that depend on the values of several variables or change several variables. See the chapter on Declared Properties in Apple's "The Objective C Programming Language".

The page was last updated Tuesday, March 27, 2012 3:15 PM