根据Xcode发行说明,Apple一直在“审核”其现有的API,以删除隐式解包的可选控件。这意味着T!它们的API会代替T或T?在适当的地方返回。
T!
T
T?
他们在哪里做?如何注释/包装现有的Objective-C代码(尤其是库),以使其更易于在Swift中使用?
Xcode 6.3增加了对在Objective-C中注释可空性的官方支持。
值的空性可以通过注释与关键字的类型声明__nullable,__nonnull并__null_unspecified(默认值)。在属性和方法的关键字nullable,nonnull和null_unspecified。
__nullable
__nonnull
__null_unspecified
nullable
nonnull
null_unspecified
Xcode发行说明中的示例
- (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部分的默认设置。
NS_ASSUME_NONNULL_BEGIN // nonnull is the default here NS_ASSUME_NONNULL_END
这消除了很多噪音,因为接受和处理nil的方法通常是例外,而不是规则。就个人而言,我会将其用于所有审核的API。
null_resettable是一个额外的注释,用于不常见的情况,您可以 将 属性 设置 为nil,但永远不会 为 nil(因为它将重置为默认值)。
null_resettable
@property (nonatomic, retain, null_resettable) UIColor *tintColor;
就个人而言,对于新代码,我会避免这种行为。此类属性的混合性质不适用于Swift。
Xcode 7添加了对在Objective-C中注释通用类型的支持。
NSArray,NSSet和NSDictionary(会自动桥接到Swift的Array,Set并Dictionary可以使用其内容类型进行注释。
NSArray
NSSet
NSDictionary
Array
Set
Dictionary
@property NSArray<NSString *> *stringArray; @property NSSet<NSString *> *stringSet; @property NSDictionary<NSString *, NSString *> *stringDict;
还有一个__kindof关键字告诉Objective-C编译器不太严格,允许向下转换。但这并不影响Swift方面。
__kindof
@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>。
@implementation
id
NSObject *
id<NSCopying>