在Objective-C中,我为NSObject
创建了一个非常方便的类别(Swift术语中的扩展),它增加了在运行时向任何NSObject
添加任意键/值对的能力。它使用关联对象将可变字典附加到对象,然后提供get和set方法,从字典中获取/设置键/值对。它只有几行代码。
这样就可以在运行时将任意键/值对附加到任何对象上,包括系统创建的对象。这是关键。在某些情况下,系统框架会返回一个对象给你,你需要能够将值附加到它上面。
这个技巧还可以创建具有新示例变量的类别(好吧,实际上并不存在,但它确实允许您向类别中的对象添加新的状态变量)。
这在Swift 1.2中是不可能的,因为:
- Swift并没有像Objective-C中的NSObject那样为所有对象提供一个基类。它使用AnyObject,这是一个协议。
- Swift 1.2不允许对协议进行扩展。
在Swift 1.2下我不得不给予这个。
但是Swift 2允许对协议进行扩展。我想“太好了,现在我可以添加我的扩展了,它允许我向AnyObject添加键/值对!”
没有欢乐。
当我尝试为AnyObject创建扩展时:
extension AnyObject: AssociatedObjectProtocol
我收到错误消息
无法扩展“AnyObject”协议
啊!太接近了,但是没有。看起来语言明确禁止扩展AnyObject。为什么会这样,有什么办法吗?
我并不经常在NSObject上使用我的分类,但是当我这样做的时候,它是一个救星。我想把它添加到我在Swift中的技巧包中。
我可以像在Objective-C中那样将它添加到NSObject中,但这意味着它只适用于从NSObject继承的对象--这使得它不适用于原生Swift类。
3条答案
按热度按时间wlsrxk511#
不幸的是,没有一个解决方案能完全满足您的需求。因此,我建议您创建一个协议,该协议具有一个扩展以添加默认实现:
这种方法并不能使所有的类自动符合这个协议(但只有类可以符合它),所以你必须让它们自己符合这个协议,因为你并不经常使用这个协议,这是一个合理的解决方案。
roejwanj2#
沿着@Qbyte的回答,声明
NSObject
符合一个协议意味着整个可可/UIKit/Foundation领域中的几乎每个类都将继承该功能:您已经将99%的Apple框架类与
MyProtocol
相一致,您可以通过继承NSObject
或简单地与之一致来使您自己的类与MyProtocol
相一致。fumotvh33#
我觉得你已经有了答案。扩展
NSObject
在Swift中也能完美地工作。(也许不是6年前的事🥲)extension NSObject { }
个