MKMapSnapshotter initWithOptions nullability

MKMapSnapshotter has the following constructor (within NS_ASSUME_NONNULL_BEGIN):

- (instancetype)initWithOptions:(MKMapSnapshotOptions *)options NS_DESIGNATED_INITIALIZER;

Which means an options param must be supplied. However the documentation contradicts this, stating “If you specify nil for this property, the snapshotter uses a set of default options that capture an image of the current user’s country”, thus it should be tagged nullable:

- (instancetype)initWithOptions:(nullable MKMapSnapshotOptions *)options NS_DESIGNATED_INITIALIZER;

This is odd because the MapKit API has been updated for nullability so I think maybe was skipped because it wasn’t straightforward. Using a decompiler we can see the code has problems, rather than the init being disallowed it actually exists and looks like this:

- (instancetype)init{
    return [self initWithOptions:nil];

And the initWithOptions checks for the nil param and creates an instance of MKMapSnapshotOptions (which has all the settings needed in its default states. This is actually not the correct way to implement designated initializers and initWithOptions should actually disallow null and the init should be:

- (instancetype)init{
    return [self initWithOptions:[MKMapSnapshotOptions.alloc init]];

I think the best way to resolve this is just to add init to the header and document that it will use a default MKMapSnapshotOptions and remove the nil options allowed to initWithOptions in the documentation. That is better than making init NS_UNAVAILABLE and adding nullable to initWithOptions because its what coders who understand designated inits expect.

The Reason NSFetchedResultsChangeUpdate Is so Buggy

Always wondered why NSFetchedResultsChangeUpdate is so buggy? The reason is Apple don’t actually use it in their own apps. Instead, what they do is have a UITableViewCell subclass with a custom property setter for the object where they add KVO for only the properties they are interested in updates to, e.g. ones that require updating the cell’s views. This is a pretty good optimisation if you have a complicated object that has lots of non-user properties being updated all the time, e.g. that have server info for remote objects. They don’t go as far as updating each label for each key change, they just update all the views when any of them change. They do some times use `NSObject`’s `cancelPerformSelector` to batch the updates into one UI update. And they might also cache some data, e.g. a count of relational data. They also can use KVO contexts in really interesting ways, like using the context to “group” key paths that all have the same outcome, which saves checking the key is say in a certain array of keys that require view updates.

It makes me so sad to see so many people struggle with `NSFetchedResultsChangeUpdate` and `NSFetchedResultsChangeMove` I wish more people knew to instead go the KVO route. I think it would be cool if when creating an Xcode project they had varying levels of templates. So this KVO usage could perhaps be in an advanced core data app template and the original in a novice one, along with a health warning about not using it if you have table sections or have objects with many non-user visible properties.

I put an example in this sample code. You can see in the example controller there is no longer `NSFetchedResultsChangeUpdate` being used, and also note the workaround for UITableView moveRows not working properly across sections, also something Apple do.

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:


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


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

@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


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.

Modern way to register NSUserDefaults

Here is a modern way to register user defaults. It uses dispatch_once to ensure the registration only happens once and performs it lazily on the first access. Keeps your defaults all on the one place. Also it is implemented as a global block in the class.

NSInteger (^countBeforeAlerting)(void) = ^NSInteger(void) {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        [[NSUserDefaults standardUserDefaults] registerDefaults:@{@"CountBeforeAlerting" : @10}];
    return [[NSUserDefaults standardUserDefaults] integerForKey:@"CountBeforeAlerting"];

Default behaviour of UISplitViewController collapseSecondaryViewController

The documentation for UISplitViewControllerDelegate collapseSecondaryViewController says:

When you return NO, the split view controller calls the collapseSecondaryViewController:forSplitViewController: method of the primary view controller, giving it a chance to do something with the secondary view controller’s content. Most view controllers do nothing by default but the UINavigationControllerclass responds by pushing the secondary view controller onto its navigation stack.

Similarily, for separateSecondaryViewControllerFromPrimaryViewController it says:

When you return nil from this method, the split view controller calls the primary view controller’s separateSecondaryViewControllerForSplitViewController: method, giving it a chance to designate an appropriate secondary view controller. Most view controllers do nothing by default but the UINavigationControllerclass responds by popping and returning the view controller from the top of its navigation stack.

I thought it might be interesting to try to implement this magic behaviour to help understand what is going on and thus provide a starting point for customisation.

- (BOOL)splitViewController:(UISplitViewController *)splitViewController collapseSecondaryViewController:(UIViewController *)secondaryViewController ontoPrimaryViewController:(UIViewController *)primaryViewController {
    if ([secondaryViewController isKindOfClass:[UINavigationController class]] && [[(UINavigationController *)secondaryViewController topViewController] isKindOfClass:[DetailViewController class]] && ([(DetailViewController *)[(UINavigationController *)secondaryViewController topViewController] detailItem] == nil)) {
        // Return YES to indicate that we have handled the collapse by doing nothing; the secondary controller will be discarded.
        return YES;
    } else {
        // push the secondary view controller onto the primary's navigation stack
        UINavigationController *nav = (UINavigationController *)primaryViewController;
        [nav pushViewController:secondaryViewController animated:NO];
        return YES;


- (nullable UIViewController *)splitViewController:(UISplitViewController *)splitViewController separateSecondaryViewControllerFromPrimaryViewController:(UIViewController *)primaryViewController{

    // respond by popping and returning the view controller from the top of its navigation stack
    UINavigationController *nav = (UINavigationController *)primaryViewController;
    return [nav popViewControllerAnimated:NO];


It’s strange it is possible to push the secondary navigation controller , since usually that exceptions with “Pushing a navigation controller is not supported”. Turns out within the push method it checks a private property _allowNestedNavigationControllers to allow it to pass in this case, and it must have been set by the split view controller at some point. These kind of tricks are really annoying because gives inconsistent behaviour and thus lowers developer confidence in the APIs.
It’s interesting to call: [(UINavigationController *)secondaryViewController setViewControllers:nil]; before pushing because it throws an exception that proves that nested navigation controllers are being used: Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Cannot display a nested UINavigationController with zero viewControllers

I find using the plus iPhone simulator useful for testing the split controller because in portrait it is compact width but rotating to landscape it moves to regular width.

ObjC Delegation and Notifications

I was researching the different ways people are implementing the part of MVC where the model notifies the controller about new data. A limitation of the delegate pattern is only one class can be the delegate, for other classes to listen then they need to use Notification Center notifications (or use a custom multi-cast delegate). Normally when the model class is called to say, insert an object, it would use the standard routine to check the delegate responds to the selector, and then call the delegate method as defined on the protocol. Then when reading some Apple’s delegations article I noticed something rather interesting:

Delegation and Notifications
The delegate of most Cocoa framework classes is automatically registered as an observer of notifications posted by the delegating object. The delegate need only implement a notification method declared by the framework class to receive a particular notification message. Following the example above, a window object posts an NSWindowWillCloseNotification to observers but sends a windowShouldClose: message to its delegate.

The interesting point here is that the delegate is registered as an observer, which is different from calling the delegate method directly. To check this was a correct statement I went to the gold mine that is the GNUStep source code for NSWindow (Github Mirror) and found this very nifty piece of code:

- (void) setDelegate: (id)anObject
  if (_delegate)
      [nc removeObserver: _delegate name: nil object: self];
  _delegate = anObject;
#define SET_DELEGATE_NOTIFICATION(notif_name) \
if ([_delegate respondsToSelector: @selector(window##notif_name:)]) \
[nc addObserver: _delegate \
selector: @selector(window##notif_name:) \
name: NSWindow##notif_name##Notification object: self]


So sure enough, it adds the delegate as an observer, and only doing so if it responds to the selector. It’s is a pretty good optimisation because now at each event only the notification needs to be posted. Previously, the delegate performing the selector would be checked every time (still done this way for delegate methods that contain data). I also really like the macro. The only problem is the notifications are rather primitive in that they contain no data about the reason, they only contain the object self. In seeing this implementation it sparked my interest to investigate if Apple implemented it the same way, which could be tested by removing the delegate as an observer and then seeing if the delegate method is no longer called, don’t think I’ll bother just now though.

NSArray @property backed by a NSMutableArray

Saw a bunch of posts today on Stack Overflow asking how to implement this:

NSArray @property backed by a NSMutableArray

Hiding privately mutable properties behind immutable interfaces in Objective-C (my answer)

Protect from adding object to NSMutableArray in public interface

Having readonly nsarray property and nsmutable array not readonly with the same name and _ in xcode 4.2 vs 4.5

How to expose an NSMutableArray as an NSArray as a return type from a method

The main reason is to expose an array as immutable in the public interface, to convey that it shouldn’t be modified externally, but can be mutated internally. This is a typical thing you would want to do in a Model class, e.g. having an insertObject method and then notifying controllers via a delegate and notifications. One of the stumbling blocks I noticed is people were trying to implement is solely with their knowledge of properties, where you can redefine a readonly property as readwrite internally using a category, unfortunately you cannot change its type. With some understanding of ObjC before automatic synthesis the solution is to manually implement the ivar that backs the property, like this:

.h file:

@interface Model : NSObject

@property (nonatomic, strong) NSArray *objects;


// todo: delegate

.m file:

@implementation Model{
    NSMutableArray* _objects;

        _objects = [[NSMutableArray alloc] init];
    [_objects addObject:object];


Just one of the many reasons developers have such a difficulty extracting their model from the view controller in Apple’s default project templates.