0

I have a ClassA that defines a property:

@interface ClassA : NSObject
@property (nonatomic) CGPoint property;
@end

The implementation doesn't override the accessors.

ClassB overrides the setter to do some additional work:

- (void)setProperty:(CGPoint)property {
    [super setProperty:property];
    [self someAdditionalWork];
}

In an other method of ClassB I try to set this property via the super setter, to skip the additional work:

- (void)otherMethodInClassB {
    // ...
    super.property = newValue;
    // ...
}

When I do this, the KVO notifications for the property are not sent. If I do the same thing, but use self, the KVO notifications work as expected:

- (void)otherMethodInClassB {
    // ...
    self.property = newValue;
    // ...
}

What's going on here? Is this the expected behavior? I couldn't find anything that would say so.

Jawap
  • 2,463
  • 3
  • 28
  • 46

1 Answers1

5

I'm not sure if this is documented, but this is the expected behavior.

Automatic KVO notifications work by silently changing your instance's class in runtime from original ClassB to an auto-generated subclass NSKVONotifying_ClassB which overrides all the required setter methods to do those willChange.../didChange... calls for you. By calling super, you effectively skip all that magic and invoke the original setter, which only does bare value assignment.

P.S. This blog post digs into deeper details of this: https://www.mikeash.com/pyblog/friday-qa-2009-01-23.html

hamstergene
  • 24,039
  • 5
  • 57
  • 72
  • Hm, interesting. But wouldn't the super setter also be silently changed then? Is there a recommended way to fix this problem? Should I deactivate automatic KVO in ClassB and add the will/didChange calls in my setter? – Jawap Jul 15 '14 at 14:31
  • The `super` calls still invoke the original superclass, or course, just as methods like `class` and `className` keep pretending like nothing happened — there may be more quirks, I'm not sure. The easiest way to workaround your situation would be to manually invoke `willChange...`/`didChange...` around call to `super`. I can't advice better without knowing what are you trying to accomplish, but problems like this may be an indication that you need to rethink your class design and/or implementation. – hamstergene Jul 15 '14 at 15:09