如何注释在Swift中使用的Objective-C API(例如返回类型) [英] How to annotate Objective-C APIs for use in Swift (e.g. return types)
问题描述
根据Xcode发行说明,Apple一直在审核"其现有API,以删除隐式解包的可选控件.这意味着它们的API会在适当的情况下返回T
或T?
而不是T!
.
According to the Xcode release notes, Apple has been "auditing" their existing APIs to remove implicitly unwrapped optionals. That means that instead of T!
, their APIs will return T
or T?
where appropriate.
他们在哪里做?如何注释/包装现有的Objective-C代码(尤其是库),使其更易于在Swift中使用?
Where do they do this? How can I annotate/wrap my existing Objective-C code (especially libraries) to make it cleaner to use from Swift?
推荐答案
Xcode 6.3/Swift 1.2
Xcode 6.3新增了对在Objective-C中注释可空性的官方支持.
Xcode 6.3/Swift 1.2
Xcode 6.3 added official support for annotating nullability in Objective-C.
可以通过使用关键字__nullable
,__nonnull
和__null_unspecified
(默认值)注释类型来声明值的可空性.在属性和方法中,关键字为nullable
,nonnull
和null_unspecified
.
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
.
Xcode发行说明中的示例
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;
更改默认值
null_unspecified
(转换为T!
)是所有现有代码的默认设置.一项有用的功能是可以更改API部分的默认设置.
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
这消除了很多噪音,因为接受和处理nil的方法通常是例外,而不是规则.就个人而言,我会将其用于所有审核的API.
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
是一个附加注释,用于不常见的情况,在这种情况下,您可以将属性设置为nil,但永远不会 nil(因为它会重置设置为默认值).
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;
就个人而言,对于新代码,我会避免这种行为.这种属性的混合性质不适用于Swift.
Personally, I would avoid this behavior for new code. The hybrid nature of such properties isn't a good fit for Swift.
Xcode 7添加了对在Objective-C中注释泛型类型的支持.
Xcode 7 adds support for annotating generic types in Objective-C.
NSArray
,NSSet
和NSDictionary
(它们自动桥接到Swift的Array
,Set
和Dictionary
)可以用其内容类型进行注释.
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<NSString *> *stringArray;
@property NSSet<NSString *> *stringSet;
@property NSDictionary<NSString *, NSString *> *stringDict;
还有一个__kindof
关键字,它告诉Objective-C编译器不太严格,允许向下转换.但这并不影响Swift方面.
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.
@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<NSCopying>> : NSObject
- (void)addObject:(T)object;
@end
@implementation
不了解T
,因此像往常一样使用id
/NSObject *
/id<NSCopying>
.
The @implementation
doesn't know about T
and uses id
/NSObject *
/id<NSCopying>
as it always did.
这篇关于如何注释在Swift中使用的Objective-C API(例如返回类型)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!