根据Xcode的发布说明,Apple已经"审计"他们现有的API来删除隐式解包的选项。这意味着,而不是T!
,他们的API将在适当的时候返回T
或T?
。
他们在哪里这样做?如何对现有的Objective-C代码(尤其是库)进行注释/包装,以使其在Swift中使用更清晰?
答案 0 :(得分:16)
Xcode 6.3增加了对Objective-C中注释可空性的官方支持。
可以通过使用关键字__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,但它永远不会 为零(因为它重置为默认值。)
@property (nonatomic, retain, null_resettable) UIColor *tintColor;
就个人而言,我会为新代码避免这种行为。这些属性的混合性质不适合Swift。
Xcode 7增加了对在Objective-C中注释泛型类型的支持。
NSArray
,NSSet
和NSDictionary
(自动桥接到Swift的Array
,Set
和Dictionary
可以使用该类型进行注释他们的内容。
@property NSArray<NSString *> *stringArray;
@property NSSet<NSString *> *stringSet;
@property NSDictionary<NSString *, NSString *> *stringDict;
还有__kindof
关键字告诉Objective-C编译器不那么严格并允许向下转换。但它不会影响Swift方面。
@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>
。
答案 1 :(得分:11)
我相信目前有办法做到这一点。看起来信息正在编译为
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphonesimulator
在
等文件中UIKit.apinotesc
UIKit.swiftdoc
UIKit.swiftmodule
*.swiftmodule
类是由Xcode生成的,作为swift构建的一部分,但附加信息可能在.apinotesc
文件中,这似乎没有记录形式的生成它那一刻。
但是,swift
命令有一个-apinotes
选项,用于生成此选项。你可以从/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphonesimulator/UIKit.apinotesc
看到你可以解析它:
xcrun swift -apinotes -binary-to-yaml -o=- /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphonesimulator/UIKit.apinotesc
这会生成一个YAML文件,如下所示:
Classes:
- Name: NSFileProviderExtension
Availability: available
AvailabilityMsg: ''
Methods:
- Selector: 'URLForItemWithPersistentIdentifier:'
MethodKind: Instance
Nullability: [ N ]
NullabilityOfRet: U
Availability: available
AvailabilityMsg: ''
如果我是一个博彩人(我不是),我会说MethodKind确定它是Instance
还是Class
并且Swift正在使用Nullability确定它是否是可选的。我怀疑:
U
- (隐含地)解包可选O
- 可选N
- 非可选?但这些都是疯狂的猜测。