Search code examples
objective-cinstance-variablesgetter-setteraccessor

Private variables in Objective-C


The cocoa Dev tutorial states that all instance variables are private when declared

Accessors

All instance variables are private in Objective-C by default, so you should use accessors to get and set values in most cases. There are two syntaxes. This is the traditional 1.x syntax:

[photo setCaption:@"Day at the Beach"];
output = [photo caption];

The code on the second line is not reading the instance variable directly. It's actually calling a method named caption. In most cases, you don't add the "get" prefix to getters in Objective-C.

Wouldn't it be easier not to need accessors every time you wanted the value? Why are they automatically declared private?


Solution

  • Wouldn't it be easier not to need accessors every time you wanted the value?

    Maybe it would be "easier", but in most cases, it would simply be incorrect.

    Setters are a better example, but there's a need arising from the use of object-returning getters as well. The typical (autogenerated) implementation of such a getter is equivalent with something like

    - (Foo *)foo {
        return [[_foo retain] autorelease];
    }
    

    which is not a coincidence -- if you simply poked around with the object's instance variable directly, then as soon as the containing object is deallocated, its instance variable would be deallocated as well, so it would be an error to use a property of an object after its deallocation.

    With setters, the list of problems is even longer. Again, there's the problem of ownership: a typical setter does something like

    - (void)setFoo:(Foo *)newFoo {
        [newFoo retain];
        [_foo release];
        _foo = newFoo;
    }
    

    Again, if you were messing with the ivar directly, you would either simply leak memory or would need to keep track of ownership manually, explicitly, which violates DRY (and is vastly error-prone).

    Then, key-value observation couldn't work either. If you just change the pointer inside the object, the registered observers wouldn't be informed of that. It's the responsibility of the setter (among others) to dispatch the appropriate key-value observer messages when a property is changed.