Swift 4.1协议弱属性弃用后,OC类实现协议的属性问题
解决Objective-C实现Swift协议时的弱属性问题
这个问题我之前在项目里也踩过坑,Swift 4.1之后协议里不能直接声明weak属性,导出到Objective-C头文件后默认是强引用,确实有点棘手。下面给你几个实用的解决方案:
方案一:在Objective-C类中直接声明weak属性
这是最直接的办法,你可以在Objective-C类里把协议要求的属性重新声明为weak,编译器会自动生成符合协议要求的getter/setter方法,完全满足协议约束:
Objective-C头文件(.h):
#import "MyProject-Swift.h" @interface MyObjCClass : NSObject <MyProtocol> // 直接声明为weak属性,覆盖协议默认的强引用 @property (nonatomic, weak) id<OtherProtocol> myProperty; @end
Objective-C实现文件(.m):
#import "MyObjCClass.h" @implementation MyObjCClass // 不需要额外实现getter/setter,@property会自动生成 @end
这种方法适合只有少数Objective-C类需要遵循协议的场景,简单粗暴见效快。
方案二:在Swift中给协议添加默认实现(关联对象)
如果有多个Objective-C类要遵循这个协议,可以在Swift里给协议写一个默认实现,用关联对象存储weak属性,这样所有遵循协议的NSObject子类都能自动拥有弱属性的实现:
Swift代码:
@objc protocol MyProtocol { var myProperty: OtherProtocol? { get set } } @objc protocol OtherProtocol: class {} // 定义关联对象的唯一标识Key private var MyPropertyAssociationKey: UInt8 = 0 extension MyProtocol where Self: NSObject { var myProperty: OtherProtocol? { get { return objc_getAssociatedObject(self, &MyPropertyAssociationKey) as? OtherProtocol } set { // 用OBJC_ASSOCIATION_WEAK实现弱引用自动置nil的特性 objc_setAssociatedObject( self, &MyPropertyAssociationKey, newValue, .OBJC_ASSOCIATION_WEAK ) } } }
这样Objective-C类只要遵循MyProtocol,不需要写任何额外代码,就能直接使用myProperty这个弱属性,非常省心。
方案三:拆分属性为getter/setter方法
如果你不想用关联对象,也可以把协议里的属性拆分成对应的getter和setter方法,然后在Objective-C类里手动实现这些方法,内部用weak变量存储:
修改后的Swift协议:
@objc protocol MyProtocol { func getMyProperty() -> OtherProtocol? func setMyProperty(_ value: OtherProtocol?) } @objc protocol OtherProtocol: class {}
Objective-C类实现:
#import "MyProject-Swift.h" @interface MyObjCClass () // 内部用weak变量存储 @property (nonatomic, weak) id<OtherProtocol> _myProperty; @end @implementation MyObjCClass - (id<OtherProtocol>)getMyProperty { return self._myProperty; } - (void)setMyProperty:(id<OtherProtocol>)value { self._myProperty = value; } @end
这种方法更灵活,适合需要对属性访问添加自定义逻辑的场景。
内容的提问来源于stack exchange,提问作者KPM
相关产品推荐
相关产品推荐

