Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to write nonnull-annotation in init?

Now in objective-c there are two new annotations: nonnull and nullable.
Which of them should I use for return type specification of init method?

- (instancetype)init {
    if (self = [super init]) {
        // ...
    }
}

Voice for nullable:
There is an "if" to check what [super init] returns and there is no guarantee it never returns nil.

Voice for nonnull:
I don't know real cases when init returns nil and I never check it.

like image 799
Mikhail Avatar asked Jul 13 '15 09:07

Mikhail


People also ask

What does javax annotation NonNull do?

@NonNull – The compiler can determine cases where a code path might receive a null value, without ever having to debug a NullPointerException. @ReadOnly – The compiler will flag any attempt to change the object.


2 Answers

For an arbitrary class, the docs for -init state:

Return Value: An initialized object, or nil if an object could not be created for some reason that would not result in an exception.

A random class's init method can return nil. If you're returning the result of [super init] from a subclass of that class, there's a possibility that the return will be nil. Your class should appropriately annotate its init method as nullable if it returns the result of a nullable [super init].

Each specific superclass object's init implementation must be inspected to determine if the subclass's call to [super init] can or will not return nil in turn.

This would indicate that your method's annotation should be nullable, unless you have confirmed that the result of [super init] will not be nil.

For direct subclasses of NSObject, specifically:

The init() method defined in the NSObject class does no initialization; it simply returns self. In terms of nullability, callers can assume that the NSObject implementation of init() does not return nil.

Thus for classes inheriting directly from NSObject, -init can be marked as nonnull.

If your class returns nil:

It's possible that the result of [super init] is nonnull, but your class's implementation of init returns nil in response to some other condition.

- (instancetype)init {
    if (self = [super init]) { // nonnull

        if (someFailureCondition) {
            return nil; // nullable
        }

    }

    return self;
}

In this case, your implementation should of course be annotated nullable.

like image 148
pkamb Avatar answered Nov 16 '22 03:11

pkamb


You can assume that [[NSObject alloc] init] will never fail. Here is what documentation actually says:

The init method defined in the NSObject class does no initialization; it simply returns self. In terms of nullability, callers can assume that the NSObject implemetation of init does not return nil.

Reference: https://developer.apple.com/reference/objectivec/nsobject/1418641-init?language=objc

like image 29
almas Avatar answered Nov 16 '22 03:11

almas