在Objective-C中,我创建了一个非常方便的NSObject
类别(Swift术语的扩展名),它增加了在运行时向任何NSObject
添加任意键/值对的功能。它使用关联对象将可变字典附加到对象,然后提供get / set方法,用于从/到该字典获取/设置键/值对。它只有几行代码。
这使得可以在运行时将任意键/值对附加到ANY对象,包括由系统创建的对象。这是关键。在某些情况下,系统框架会向您返回一个对象,您需要能够为其附加值。
这个技巧还可以创建具有新实例变量的类别。 (好吧,他们不是真的,但是因为它确实允许你向一个类别中的对象添加新的状态变量。)
这在Swift 1.2中是不可能的,因为:
我不得不放弃Swift 1.2下的这个。
但Swift 2允许扩展协议。我想"很好,现在我可以添加我的扩展,让我可以为AnyObject添加键/值对!"
没有快乐。
当我尝试为AnyObject创建扩展时:
extension AnyObject: AssociatedObjectProtocol
我收到错误消息
' AnyObject'协议无法扩展
Arghh!如此接近,但不是。似乎该语言明确禁止扩展AnyObject。为什么会这样,有什么办法吗?
我不经常在NSObject上使用我的类别,但是当我这样做时,它就是救星。我想把它添加到我在Swift中的技巧包中。
我可以像在Objective-C中那样将它添加到NSObject,但这意味着它只适用于从NSObject继承的对象 - 使其不适用于本机Swift类。
答案 0 :(得分:13)
不幸的是,一个与您想要完全相同的解决方法并不存在。所以我建议制作一个扩展的协议来添加默认实现:
protocol A: AnyObject {}
// in Swift you would rather use this
protocol A: class {}
// add default implementations
extension A {
func aMethod() {
// code
}
}
// Example
class B: A {}
// use the method
B().aMethod()
这种方法不会使所有类自动符合此协议(但只有类可以符合它)。所以你必须让自己符合自己。既然你不能使用它,这将是一个合理的解决方案。
答案 1 :(得分:6)
根据@ Qbyte的回答,声明NSObject
符合协议意味着整个Cocoa / UIKit / Foundation世界中的几乎每个类都将继承该功能:
protocol MyProtocol {
func doSomething()
}
extension MyProtocol {
func doSomething() {
print("This is me, doing something.")
}
}
extension NSObject: MyProtocol { }
您刚刚将99%的Apple框架类符合MyProtocol
。您可以通过继承MyProtocol
或简单地符合它来使您自己的类符合NSObject
。