Custom setter and getters

March 25th, 2011

In Objective-C, a property can have the following attributes applied to it:

  • atomic
  • nonatomic
  • assign
  • retain
  • copy

The scenerio is that these attributes are applied to the properties for us but what happens if we want setting/getting a property's value to have a side-effect?

In this article, I implement the different possible combinations of property attributes to show how we can have custom getters and setters in our .m files while still honouring the property attributes declared in our .h files.

Non-atomic, retained property

Setter:
- (void)setObject:(anObject *)theObject{
      if (object != theObject) { //make you are not attempting to set the same object as is already set
            [object release];
            object = [theObject retain];
      }
}
Getter:
- (anObject *)object{

    anObject *objectToBeReturned = [object retain];
    return [objectToBeReturned autorelease];
}

Non-atomic, copied property:

Setter:
- (void)setObject:(anObject *)theObject{
      if (object != theObject) { //make you are not attempting to set the same object as is already set
            [object release];
            object = [theObject copy];
      }
}
Getter:
- (anObject *)object{

    anObject *objectToBeReturned = [object retain];
    return [objectToBeReturned autorelease];
}

Assigned property:

Setter:
- (void)setObject:(anObject *)theObject{
      if (object != theObject) { //make you are not attempting to set the same object as is already set
            object = theObject;
      }
}
Getter:
- (anObject *)object{
    return objectToBeReturned
}

Atomic, retained property:

Setter:
- (void)setObject:(anObject *)theObject{

    @synchronized(self) {//don't allow any other updates to occur until finished
        if (object != theObject) { //make you are not attempting to set the same object as is already set
            [object release];
            object = [theObject retain];
        }
    }
}
Getter:
- (anObject *)object{

    @synchronized(self) {
        id objectToBeReturned = [object retain];
    }

    return [objectToBeReturned autorelease];
}

Please note if KVO automatic notification is turned off in the above setter methods you will have to surround object = [theObject retain]; with:

[self willChangeValueForKey:@"object"];
object = [theObject retain];
[self didChangeValueForKey:@"object"];

What do you think? Let me know by getting in touch on Twitter - @wibosco