Search code examples
objective-ccore-datasetter

Custom setter methods in Core-Data


I need to write a custom setter method for a field (we'll call it foo) in my subclass of NSManagedObject. foo is defined in the data model and Xcode has autogenerated @property and @dynamic fields in the .h and .m files respectively.

If I write my setter like this:

- (void)setFoo: (NSObject *)inFoo {
    [super setFoo: inFoo];
    [self updateStuff];
}

then I get a compiler warning on the call to super.

Alternatively, if I do this:

- (void)setFoo: (NSObject *)inFoo {
    [super setValue: inFoo forKey: inFoo];
    [self updateStuff];
}

then I end up in an infinite loop.

So what's the correct approach to write a custom setter for a subclass of NSManagedObject?


Solution

  • Here is the Apple way for overriding NSManagedObject properties (without breaking KVO), in your .m file:

    @interface Transaction (DynamicAccessors)
    - (void)managedObjectOriginal_setDate:(NSDate *)date;
    @end
    
    @implementation Transaction
    @dynamic date;
    
    - (void)setDate:(NSDate *)date
    {
        // invoke the dynamic implementation of setDate (calls the willChange/didChange for you)
        [self managedObjectOriginal_setDate:(NSString *)date;
    
        // your custom code
    }
    

    managedObjectOriginal_propertyName is a built-in magic method you just have to add the definition for. As seen at bottom of this page What's New in Core Data in macOS 10.12, iOS 10.0, tvOS 10.0, and watchOS 3.0