Objective-C class 中的弱 属性 实现了 Swift 协议

A weak property in Objective-C class implementing a Swift protocol

在 Swift 4.1 中,弱属性已经 deprecated in protocols,因为编译器无法强制执行它。符合协议的 class 有责任定义 属性 的内存行为。

@objc protocol MyProtocol {
  // weak var myProperty: OtherProtocol /* Illegal in Swift 4.1 */
  var myProperty: OtherProtocol? { get set }
} 
@objc protocol OtherProtocol: class {}

然而,这会作为一个强大的 属性 导出到 MyProject-Swift.h

@protocol MyProtocol
@property (nonatomic, strong) id <OtherProtocol> _Nullable myProperty;
@end

现在我遇到一个问题,当 class 写在 Objective-C 中时:

@interface MyClass: NSObject<MyProtocol>
@property (nonatomic, weak) id <OtherProtocol> myProperty;
@end

错误状态 retain (or strong)' attribute on property 'myProperty' does not match the property inherited

我该如何解决这个问题?

根据@Hamish 的评论,在 Swift 4.2 解决问题之前,一个可行的解决方法不会强制重写 Objective-C 中的协议并且影响有限,将使用clang 的诊断编译指示指令。

@interface MyClass: NSObject<MyProtocol>
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch"
@property (nonatomic, weak) id <OtherProtocol> myProperty;
#pragma clang diagnostic pop
@end

你的问题确实是生成的-Swift.h文件中的强引用。 我发现您仍然可以通过在 属性 之前添加 @objc weak 将 属性 标记为弱,因此它会在 Swift header 不会触发 Swift 4.1 弃用警告。

@objc protocol MyProtocol {
  // weak var myProperty: OtherProtocol /* Illegal in Swift 4.1 */
  @objc weak var myProperty: OtherProtocol? { get set }
}