Как сделать протоколы и их расширения в свойствах магазина Swift? - PullRequest
0 голосов
/ 09 марта 2019

Ниже приведен обходной путь для «проблемы», заключающейся в том, что протоколы и их расширения в Swift не хранят свойства. Кажется, что это «работает», но мне интересно, по каким причинам люди могут избегать этого?

fileprivate var strings: [String] = []

protocol SomeProat {
    func add(someString: String)
}

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

(я понимаю, что этот вопрос можно интерпретировать как субъективный, кстати).

1 Ответ

3 голосов
/ 09 марта 2019

Нет хорошего способа сделать то, что вы просите, в чистом Swift на платформах, отличных от Apple.

Если вы работаете на платформе 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"]
...