Working with custom UIView designated initializers

I have a UIView subclass, with a custom designated initializer. How should I handle the requirement to override initWithCoder:?

⚠️
This post was automatically migrated from my old blogging software, and I have not reviewed it for problems yet. Please contact me if you notice any important issues.

Update Jan. 6, 2016: I should’ve written this update earlier, so I could remember and thoroughly explain my train of thought. But for future reference: after this Twitter discussion with Matt, you can see the approach I chose for the affected classes in our open-source photo viewer:


I have a UIView subclass, with its own custom designated initializer. (Specifically, I’m talking about NYTPhotoCaptionView from our open-source photo viewer.)

As you might expect, under Xcode 7 this produces a warning:

Method override for the designated initializer of the superclass '-initWithCoder:' not found

But I’m not sure of the best way to resolve this warning.

My first attempt was to create an -initWithCoder: implementation which would call through to super, then perform common initialization:

{% highlight objc %}

  • (instancetype)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];

    if (self) {
    [self commonInit];
    }

    return self;
    }
    {% endhighlight %}

But this results in another 2 warnings:

Convenience initializer should not invoke an initializer on 'super'

Convenience initializer missing a 'self' call to another initializer

I guess that makes sense. But this means I always have to call my view’s custom designated initializer, which doesn’t support NSCoder.

So as I see it, these are my options:

  • Mark -initWithCoder: as NS_UNAVAILABLE. This resolves the warning, but I am uncertain what will break if I go this route, and this breaks inheritance so I feel dirty using it.
  • Totally ignore any decoder passed to -initWithCoder: and call through to our designated initializer. This seems wrong, since we’re ignoring a decoder explicitly passed to us.
  • Make this class’s designated initializer another convenience initializer instead, and override all initializer methods to call through to -commonInit. This is probably the best option, with the caveat that then I need to make sure the properties passed into the initializer can be set after-the-fact.

What’s the right approach here? Get at me; I’m @cdzombak on Twitter.