How do I cleanly override a property setter?

11,867

You can override a setter/getter without having to poke around the internal state of the class (i.e. ivars) -- just call the super's methods in your overrides:

- (Thing *)thing {
    // do your extra stuff here
    //  ...

    return [super thing];
}

- (void)setThing:(Thing *)thing {
    // do your extra stuff here
    //  ...

    [super setThing:thing];
}

An alternative that might suit your problem is to use KVO.

Update

Of course, overriding setBounds might not be necessary. See this question -- layoutSubviews gets called if the frame changes, and changing the bounds causes the frame size to also be updated. So consider putting your code into layoutSubviews.

Final update

Ok, here is why Apple is never going to suddenly declare some @property items as using a non-standard method names (as you fear):

It would break everything in the app store.

Think about it this way: at compile time, any code that accesses a property using dot notation, e.g. the obj.x syntactic sugar, is converted to a message of the form [obj x]. Likewise for properties -- they are converted at compile time into regular methods. So, compiled binaries know nothing about dot notation and properties -- they just call regular selectors. So if Apple released an update to iOS that declared some public properties as having non-standard implementation methods, everything in the app store could break. Everything. There is no fault on your behalf in this scenario if your app broke like the rest -- it would be Apple's fault, not yours.

Share:
11,867
Kartick Vaddadi
Author by

Kartick Vaddadi

Earlier: IIT | Google | Solopreneur | Founder | CTO | Advisor

Updated on June 07, 2022

Comments

  • Kartick Vaddadi
    Kartick Vaddadi almost 2 years

    If I want to define a custom UIView subclass that does something when its bounds are set, how do I override the setter? Overriding setBounds seems dangerous since, if I understand correctly, the getter and setter names are not part of the public interface and could change anytime.

    Of course, I use class_copyPropertyList to query the runtime for a list of properties defined in the class, then query it for the setter's name, and finally use class_addMethod to add the method, after first getting a reference to the earlier method to use for calling the original version.

    All this seems hacky. Is there a clean way to do what I want, which is guaranteed to not break on future OS versions? Thanks.