0

以下是 Swift 中协议及其扩展不存储属性的“问题”的解决方法。它似乎“有效”,但我想知道人们可能有什么理由避免它?

fileprivate var strings: [String] = []

protocol SomeProat {
    func add(someString: String)
}

extension SomeProat {
    func add(someString: String) {
        strings.append(someString)
        print(strings)
    }
}

(我意识到这个问题可以被解释为主观的顺便说一句)。

4

1 回答 1

3

在非 Apple 平台上,没有什么好方法可以在纯 Swift 中完成您所要求的事情。

如果您在 Apple 平台(macOS、iOS、tvOS、watchOS)上,并且您的符合类型是一个类,那么您可以使用 Objective-C 运行时提供的关联对象支持:

import ObjectiveC

protocol MyProtocol: class {
    var strings: [String] { get }
    func add(someString: String)
}

private var MyProtocolSomeStringKey: UInt8 = 0

extension MyProtocol {
    var strings: [String] {
        get {
            return objc_getAssociatedObject(self, &MyProtocolSomeStringKey) as? [String] ?? []
        }
        set {
            let value = newValue.isEmpty ? nil : newValue
            objc_setAssociatedObject(self, &MyProtocolSomeStringKey, value, .OBJC_ASSOCIATION_RETAIN)
        }
    }

    func add(someString: String) {
        strings.append(someString)
    }
}

class MyObject { }
extension MyObject: MyProtocol { }

let myObject = MyObject()
myObject.add(someString: "hello")
myObject.add(someString: "world")
print(myObject.strings)
// Output: ["hello", "world"]
于 2019-03-08T21:35:40.383 回答