有没有办法为AnyObject添加扩展?

Dun*_*n C 15 protocols swift2

在Objective-C中,我创建了一个非常方便的类别(在Swift术语中的扩展) NSObject该添加到任意的键/值对添加到任何的能力NSObject在运行时.它使用关联对象将可变字典附加到对象,然后提供get/set方法,用于从/到该字典获取/设置键/值对.它只有几行代码.

这使得可以在运行时将任意键/值对附加到ANY对象,包括由系统创建的对象.这是关键.在某些情况下,系统框架会向您返回一个对象,您需要能够为其附加值.

此技巧还可以创建具有新实例变量的类别.(好吧,它们不是真的,但是它确实允许你向类别中的对象添加新的状态变量.)

这在Swift 1.2中是不可能的,因为:

  • Swift没有像Objective-C中的NSObject这样的所有对象的基类.它使用AnyObject,这是一种协议.
  • Swift 1.2不允许扩展协议.

在Swift 1.2下我不得不放弃这个.

但Swift 2允许扩展协议.我想"很好,现在我可以添加我的扩展,让我可以向AnyObject添加键/值对!"

没有快乐.

当我尝试为AnyObject创建扩展时:

extension AnyObject: AssociatedObjectProtocol
Run Code Online (Sandbox Code Playgroud)

我收到错误消息

'AnyObject'协议无法扩展

Arghh!如此接近,但不是.似乎该语言明确禁止扩展AnyObject.为什么会这样,有什么办法吗?

我不经常在NSObject上使用我的类别,但是当我这样做时,它是一个救星.我想把它添加到我在Swift中的技巧包中.

我可以像在Objective-C中那样将它添加到NSObject,但这意味着它只适用于从NSObject继承的对象 - 使其不适用于本机Swift类.

Qby*_*yte 14

不幸的是,不存在与您想要的完全相同的解决方法.所以我建议制作一个扩展的协议来添加默认实现:

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()
Run Code Online (Sandbox Code Playgroud)

这种方法不会使所有类自动符合此协议(但只有类可以符合它).所以你必须让自己符合自己.由于你不使用这个,这将是一个合理的解决方案.

  • @DuncanC伪代码是什么意思?此代码是有效的Swift 2代码. (2认同)

Aar*_*sen 6

根据@ Qbyte的回答,声明NSObject符合协议意味着整个Cocoa/UIKit/Foundation Universe中的几乎每个类都将继承该功能:

protocol MyProtocol {
    func doSomething()
}

extension MyProtocol {
    func doSomething() {
        print("This is me, doing something.")
    }
}

extension NSObject: MyProtocol { }
Run Code Online (Sandbox Code Playgroud)

你刚刚完成了99%的Apple框架类MyProtocol.您可以MyProtocol通过继承NSObject或简单地遵循它来使您自己的类符合.