How do I cleanly override a property setter?
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.
Kartick Vaddadi
Earlier: IIT | Google | Solopreneur | Founder | CTO | Advisor
Updated on June 07, 2022Comments
-
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.