简体   繁体   中英

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
}

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
  }
}

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];
 }

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.

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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM