New Way to Override NSManagedObject Properties

There is a new, yet not very well-known way to override NSManagedObject properties without needing to manually call KVO methodsĀ willChangeValueForKey etc. This is achieved using dynamic accessors prefixed with managedObjectOriginal as follows:

Department.h

@interface Department : NSManagedObject
@property (nullable, nonatomic, copy) NSString *name;
@end

Department.m

@interface Department (DynamicAccessors)
- (NSString *)managedObjectOriginal_name;
- (void)managedObjectOriginal_setName:(NSString *)newName;
@end

@implementation Department

@dynamic name;

- (NSString *)name
{
    // invoke the dynamic implementation of name
    NSString *name = [self managedObjectOriginal_name];
    // your custom code
    return name;
}

- (void)setName:(NSString *)name
{
    // invoke the dynamic implementation of setName
    [self managedObjectOriginal_setName:(NSString *)name;
    // your custom code
}

@end

As seen at bottom of What’s New in Core Data in macOS 10.12, iOS 10.0, tvOS 10.0, and watchOS 3.0.

Common Init for a UIViewController Subclass

When creating a UIViewController subclass, e.g. in a framework, which you require to support being created from both storyboards and code, it is useful to implement initialisation which works for both. That can be achieved with a common init routine as follows:

- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        [self doCommonInit];
    }
    return self;
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder{
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self doCommonInit];
    }
    return self;
}

- (void)doCommonInit{
    // init for both storyboards and code
}

Note: don’t call it _doCommonInit because Apple use that name for their own common init method! Actually it’s best avoid underscore prefix in any methods, cause that’s reserved for Apple’s use.