iosobjective-cuiviewinitwithframeobjective-c-nullability

Conflicting documentation for `[UIView initWithFrame:]`: nullable or nonnull?


Using CLANG_ANALYZER_NONNULL (i.e. -Xclang nullability), I got "Null is returned from a function that is expected to return a non-null value":

enter image description here

Using Xcode 7.3 and iOS 9.3 documentation, I checked initWithFrame: and it can return nil:

description

But UIView.h encapsulates everything with NS_ASSUME_NONNULL_BEGIN, so we can interpret the following:

interface

as:

- (nonnull instancetype)initWithFrame:(CGRect)frame NS_DESIGNATED_INITIALIZER;

So documentation explains it's nullable, while header file says it's nonnull. Which one to trust?

Should I write:

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (!self) {
        // workaround for clang analyzer
        return (void * _Nonnull)nil;
    }
    // Initialization code
    return self;
}

Or:

- (nonnull instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    // Initialization code
    return self;
}

🔴🔴🔴

UPDATE

Xcode documentation was updated and is now: initWithFrame: documentation

So no more conflict.


Solution

  • In the case of UIView's -initWithFrame initializer, the recommendation is to not defensively check the result of calling the super initializer because there is realistically nothing an application can do to recover from a failed UIView allocation.

    Also, as of Xcode 7.3 beta 4, the static analyzer no longer warns here. It now doesn't warn about returning nil from the -init, -copy, and -mutableCopy families even when these methods have a return type with a nonnull type qualifier to avoid warning on exactly this common defensive idiom.