How to annotate Objective-C APIs for use in Swift (e.g. return types)

前端 未结 2 1183
夕颜
夕颜 2020-12-08 22:39

According to the Xcode release notes, Apple has been \"auditing\" their existing APIs to remove implicitly unwrapped optionals. That means that instead of T!, t

2条回答
  •  轮回少年
    2020-12-08 22:56

    Xcode 6.3/Swift 1.2

    Xcode 6.3 added official support for annotating nullability in Objective-C.

    Nullability

    The nullability of a value can be declared by annotating the type with the keywords __nullable, __nonnull and __null_unspecified (the default). In properties and methods the keywords are nullable, nonnull and null_unspecified.

    Examples from the Xcode release notes

       - (void)registerNib:(nonnull UINib *)nib
    forCellReuseIdentifier:(nonnull NSString *)identifier;
    
    - (nullable UITableViewCell *)cellForRowAtIndexPath:(nonnull NSIndexPath)indexPath;
    
    @property (nonatomic, readwrite, retain, nullable) UIView *backgroundView;
    

    Changing the default

    null_unspecified (which translates to T!) is the default for all existing code. A useful feature is the ability to change the default for sections of your API.

    NS_ASSUME_NONNULL_BEGIN
    // nonnull is the default here
    NS_ASSUME_NONNULL_END
    

    This removes a lot of noise, since methods that accept and handle nil usually are the exception, not the rule. Personally, I would use this for all audited APIs.

    null_resettable

    null_resettable is an additional annotation that is used for the uncommon case where you can set a property to nil, but it will never be nil (because it resets to a default value).

     @property (nonatomic, retain, null_resettable) UIColor *tintColor;
    

    Personally, I would avoid this behavior for new code. The hybrid nature of such properties isn't a good fit for Swift.

    Xcode 7/Swift 2 (Beta)

    Xcode 7 adds support for annotating generic types in Objective-C.

    Generic type annotations for collections

    NSArray, NSSet and NSDictionary (which are automatically bridged to Swift's Array, Set and Dictionary can be annotated with the type of their contents.

    @property NSArray *stringArray;
    @property NSSet *stringSet;
    @property NSDictionary *stringDict;
    

    There's also the __kindof keyword that tells the Objective-C compiler to be less strict and allow downcasting. But it doesn't affect the Swift side.

    Generic type annotations for custom classes

    @interface MyArray1<__covariant T> : NSObject
    - (void)addObject:(T)object;
    @end
    
    @interface MyArray2<__covariant T : NSObject *> : NSObject
    - (void)addObject:(T)object;
    @end
    
    @interface MyArray3<__covariant T : id> : NSObject
    - (void)addObject:(T)object;
    @end
    

    The @implementation doesn't know about T and uses id/NSObject */id as it always did.

提交回复
热议问题