darksky
darksky

Reputation: 21019

Objective-C Custom Setter

Note: I am not using ARC

I have a UILabel with the following property: @property (nonatomic, retain) UILabel *someLabel; I am trying to set a custom setter. Would the following code cause a leak, since @property is actually calling retain as well?

- (void)setSomeLabel:(UILabel *)someLabel
{
    if (someLabel != self.someLabel) {
        [self.someLabel release];
        self.someLabel = [someLabel retain];
    }

    // some custom code here
}

Upvotes: 0

Views: 5139

Answers (4)

Rob Napier
Rob Napier

Reputation: 299265

Note: I am not using ARC

You really, really should.


Your setter is an infinite loop. The call to self.someLabel = ... is the exact equivalent of [self setSomeLabel:...], which causes the loop.

A correct manual setter looks like this:

- (void)setSomeLabel:(UILabel *)someLabel
{
  [someLabel retain];
  [_someLabel release];
  _someLabel = someLabel;

  // some custom code here
}

There are other common patterns. A major question is whether "some custom code" should run if the object is reset to the same value. If not, then this pattern makes more sense:

- (void)setSomeLabel:(UILabel *)someLabel
{
  if (someLabel != _someLabel) {
    [_someLabel release];
    _someLabel = [someLabel retain];

    // some custom code here
  }
}

Upvotes: 8

Nekto
Nekto

Reputation: 17877

That code will lead your app to infinite loop as using self.someLabel causes calling method setSomeLabel:.

You could try the code below for your custom setter:

 @synthesize someLabel = _someLabel;
 - (void)setSomeLabel:(UILabel *)someLabel
 {
      if (someLabel != _someLabel)
      {
           [_someLabel release];
           _someLabel = [someLabel retain];
      }

      // custom code
 }

 - (void)dealloc
 { 
     [_someLabel release];
     // ... other releases
     [super dealloc];
 }

Upvotes: 6

InsertWittyName
InsertWittyName

Reputation: 3940

I'm assuming you're not using ARC...

You are correct that you're over-retaining the someLabel that is passed in, also calling release on a property is not great!

I would use the instance variable instead of the property:

- (void)setSomeLabel:(UILabel *)someLabel
{
    if (someLabel != _someLabel) {
        [_someLabel release];
        _someLabel = [someLabel retain];
    }

    // some custom code here
}

Upvotes: 0

Shashikanth
Shashikanth

Reputation: 752

No, This is perfectly fine as you are using a custom setter here.

@Property is just equivalent to declaring the accessor methods.

@Synthesize will generate the accessor methods based on the property declaration attributes ONLY IF the setter and/or getter are NOT IMPLEMENTED.

Upvotes: 0

Related Questions