Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correctly override setter in Objective-C

I just tried to override the standard synthesised setters of a property. So far everything is fine I just set the ivar to my new value. But then I asked myself 'what happens with the retain count of retained properties'... I found no good answer that explained this to me. So I ask it here. Is there anything I have to be aware of if I override a properties setter that is set to retain and how can I do it correctly? I do not use ARC.

Here's an example:

@property(nonatomic)NSInteger number;

- (void)setNumber:(NSInteger)number {
    _number = number;  // This should be fine, since it's no retained object I want to set
}


@property(nonatomic, retain)NSObject *something;

- (void)setSomething:(NSObject *)something {
    _something = something;  // This is not fine. As far as I know you should never do sth. like this... But how do I set it correctly?
}
like image 817
E. Lüders Avatar asked Sep 11 '12 12:09

E. Lüders


2 Answers

-(void) setAnObject:(NSObject*) someObject {
    if (_anObject != someObject) {
       NSObject* savedObject = _anObject;
       _anObject = [someObject retain];
       [savedObject release];
    }
}

If you release the old pointer before retaining the new, you can have a situation where you're setting the value from a value in the old object, and the release of the old object causes the new object to go POOF! just before it's retained.

Alternatively, you could do

....
[someObject retain];
[_anObject release];
_anObject = someObject;
...
like image 166
Hot Licks Avatar answered Oct 14 '22 15:10

Hot Licks


Edited after studying accepted answer from Hot Licks

property declaration and synthesis of x

@property (nonatomic, retain) ClassX x;
@synthesize x = _x;

over-ridden setter for x

- (void)setX:(ClassX *)x;
{
  if (x != _x)
  {
    [x retain];
    [_x release];
    _x = x;
    // custom code here
  }
}
like image 27
Damo Avatar answered Oct 14 '22 13:10

Damo