新版本的变更 / Objective-C 2015: Generics and Nullability

// *** before: ***
// a pointer said nothing about nil, and whether a method could return it
// was written in the documentation - or nowhere
@interface Library : NSObject
- (Book *)bookWithTitle:(NSString *)title;   // nil when there is no such book?
- (void)addBook:(Book *)book;                // is nil allowed here?
@property (nonatomic, strong) Book *current; // may it be empty?
@end

Book *book = [library bookWithTitle:@"Moby-Dick"];
[library addBook:book];      // if book is nil the call quietly does nothing
                             // or breaks the collection deep inside

// *** in version 2015: ***
// the answer is written in the declaration and is checked by the compiler
@interface Library : NSObject
- (nullable Book *)bookWithTitle:(nonnull NSString *)title;
- (void)addBook:(nonnull Book *)book;
@property (nonatomic, strong, nullable) Book *current;
@property (nonatomic, copy, nonnull) NSString *name;
@end

[library addBook:nil];
// warning: null passed to a callee that requires a non-null argument

Book *book = [library bookWithTitle:@"Moby-Dick"];
if (book != nil)             // the compiler shows that the check is needed
    [library addBook:book];

// ⚠️ this is a hint, not a guarantee: an annotation is checked where the
// compiler can see the value, and nothing stops nil from arriving at run
// time from an unannotated place