如何为Swift中使用的Objective-C API添加注释(例如返回类型)

如何为Swift中使用的Objective-C API添加注释(例如返回类型),objective-c,swift,Objective C,Swift,根据Xcode发行说明,苹果一直在“审核”他们现有的API,以删除隐式未包装的选项。这意味着不是T,它们的API将在适当的情况下返回T或T? 他们在哪里做的?如何对现有的Objective-C代码(尤其是库)进行注释/包装,使其更易于从Swift中使用?我相信目前有一种方法可以做到这一点。看起来信息正在被编译为 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/

根据Xcode发行说明,苹果一直在“审核”他们现有的API,以删除隐式未包装的选项。这意味着不是
T
,它们的API将在适当的情况下返回
T
T?


他们在哪里做的?如何对现有的Objective-C代码(尤其是库)进行注释/包装,使其更易于从Swift中使用?

我相信目前有一种方法可以做到这一点。看起来信息正在被编译为

/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/toolschains/XcodeDefault.xctoolschain/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决定它是
实例还是
类,并且Swift正在使用Nullability来确定它是否是可选的。我怀疑:

  • U
    -(隐式)展开可选
  • O
    -可选
  • N
    -非可选
不过这些都是胡乱猜测。

Xcode 6.3/Swift 1.2 Xcode 6.3增加了官方对Objective-C中注释可空性的支持

空属性 值的可空性可以通过使用关键字
\uuuu nullable
\uuuu nonnull
\uuu null\u unspecified
来声明(默认值)。在properties和methods中,关键字是
nullable
nonnull
null\u 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\u unspecified
(翻译为
T!
)是所有现有代码的默认值。一个有用的特性是能够更改API部分的默认值

NS_ASSUME_NONNULL_BEGIN
// nonnull is the default here
NS_ASSUME_NONNULL_END
这消除了很多干扰,因为接受和处理nil的方法通常是例外,而不是规则。就我个人而言,我会将其用于所有已审核的API

空值可重设
null\u resetable
是一个附加注释,用于特殊情况,您可以将属性设置为nil,但它永远不会为nil(因为它重置为默认值)

就我个人而言,我会在新代码中避免这种行为。这些属性的混合性质不适合Swift

Xcode 7/Swift 2(测试版) Xcode 7增加了对Objective-C中注释泛型类型的支持

集合的泛型类型批注
NSArray
NSSet
NSDictionary
(它们自动桥接到Swift的
数组
Set
Dictionary
可以用它们的内容类型进行注释

@property NSArray<NSString *> *stringArray;
@property NSSet<NSString *> *stringSet;
@property NSDictionary<NSString *, NSString *> *stringDict;

@implementation
不知道
t
,像往常一样使用
id
/
NSObject*
/
id

比较(需要开发人员登录).FYI这是私人功能,可能会在未来版本中更改,恕不另行通知。这不是我们打算向您这样的第三方公开此功能的方式。很高兴相信-这是了解Swift从何处获得此信息的有用练习:)不,正如我所说,在属性和方法中不使用下划线。它的工作原理与
\uu弱
(参见)。
@property NSArray<NSString *> *stringArray;
@property NSSet<NSString *> *stringSet;
@property NSDictionary<NSString *, NSString *> *stringDict;
@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