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

时间:2014-09-09 14:35:41

标签: objective-c swift

根据Xcode的发布说明,Apple已经"审计"他们现有的API来删除隐式解包的选项。这意味着,而不是T!,他们的API将在适当的时候返回TT?

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

2 个答案:

答案 0 :(得分:16)

Xcode 6.3 / Swift 1.2

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

可空

可以通过使用关键字__nullable__nonnull__null_unspecified(默认值)对类型进行注释来声明值的可为空性。在属性和方法中,关键字为nullablenonnullnull_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

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

 @property (nonatomic, retain, null_resettable) UIColor *tintColor;

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

Xcode 7 / Swift 2(Beta)

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

集合的通用类型注释

NSArrayNSSetNSDictionary(自动桥接到Swift的ArraySetDictionary可以使用该类型进行注释他们的内容。

@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 - 非可选?

但这些都是疯狂的猜测。