如何注释用于Swift的Objective-C API(例如返回类型)

nsc*_*hum 17 objective-c swift

根据Xcode发布的说明,Apple已经"审核"了他们现有的API,以删除隐含的未解包的选项.这意味着T!,他们的API将返回TT?在适当的时候返回.

他们在哪里这样做?如何对现有的Objective-C代码(特别是库)进行注释/包装,以使其从Swift中使用更清晰?

nsc*_*hum 16

Xcode 6.3/Swift 1.2

Xcode 6.3增加了在Objective-C中注释可空性的官方支持.

可空

值的空性可以通过注释与关键字的类型声明__nullable,__nonnull__null_unspecified(默认值).在属性和方法中,关键字是nullable,nonnullnull_unspecified.

Xcode发行说明中的​​示例

   - (void)registerNib:(nonnull UINib *)nib
forCellReuseIdentifier:(nonnull NSString *)identifier;

- (nullable UITableViewCell *)cellForRowAtIndexPath:(nonnull NSIndexPath)indexPath;

@property (nonatomic, readwrite, retain, nullable) UIView *backgroundView;
Run Code Online (Sandbox Code Playgroud)

更改默认值

null_unspecified(转换为T!)是所有现有代码的默认值.一个有用的功能是能够更改API部分的默认值.

NS_ASSUME_NONNULL_BEGIN
// nonnull is the default here
NS_ASSUME_NONNULL_END
Run Code Online (Sandbox Code Playgroud)

这消除了很多噪音,因为接受和处理nil的方法通常是例外,而不是规则.就个人而言,我会将其用于所有经过审核的API.

null_resettable

null_resettable是一个额外的注释,用于不常见的情况,您可以属性设置为nil,但它永远不会 nil(因为它重置为默认值).

 @property (nonatomic, retain, null_resettable) UIColor *tintColor;
Run Code Online (Sandbox Code Playgroud)

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

Xcode 7/Swift 2(Beta)

Xcode 7增加了对在Objective-C中注释泛型类型的支持.

集合的通用类型注释

NSArray,NSSetNSDictionary(其是自动桥接到Swift的Array,SetDictionary可以用其内容的类型进行注释.

@property NSArray<NSString *> *stringArray;
@property NSSet<NSString *> *stringSet;
@property NSDictionary<NSString *, NSString *> *stringDict;
Run Code Online (Sandbox Code Playgroud)

还有一个__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
Run Code Online (Sandbox Code Playgroud)

@implementation不知道T和用途id/ NSObject */ id<NSCopying>因为它总是这样.


AlB*_*lue 11

我相信目前有办法做到这一点.看起来正在编译信息

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphonesimulator
Run Code Online (Sandbox Code Playgroud)

在文件中

UIKit.apinotesc 
UIKit.swiftdoc 
UIKit.swiftmodule
Run Code Online (Sandbox Code Playgroud)

这些*.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
Run Code Online (Sandbox Code Playgroud)

这会生成一个YAML文件,如下所示:

Classes:         
  - Name:            NSFileProviderExtension
    Availability:    available
    AvailabilityMsg: ''
    Methods:         
      - Selector:        'URLForItemWithPersistentIdentifier:'
        MethodKind:      Instance
        Nullability:     [ N ]
        NullabilityOfRet: U
        Availability:    available
        AvailabilityMsg: ''
Run Code Online (Sandbox Code Playgroud)

如果我是一个博彩人(我不是),我会说MethodKind确定它是a Instance还是a Class并且Swift正在使用Nullability来确定它是否是可选的.我怀疑:

  • U - (含蓄地)展开可选
  • O - 可选的
  • N - 非选择性?

这些都是疯狂的猜测.

  • 仅供参考,这是私有功能,可在未经预警的情况下在未来版本中更改.这不是我们打算将此功能公开给像您这样的第三方. (7认同)
  • 很高兴相信 - 这是一个有用的练习,了解Swift从哪里获取此信息:) (2认同)