Можно ли добавить наблюдателя на переменную структуры в Swift?

Внутренние системы GUI вызывают этот метод, и они передают параметр Graphics в качестве графического контекста, на который вы можете рисовать.

0
задан Anand Kore 17 January 2019 в 08:55
поделиться

3 ответа

С переменными вы можете использовать двух наблюдателей по умолчанию.

  • willSet - представляет момент, когда переменная будет установлена ​​с новым значением

  • [ 115] - представляет момент, когда переменная была установлена ​​


Также в обозревателе вы можете работать с двумя значениями. С текущей переменной в текущем состоянии и с постоянной зависимой от наблюдателя

struct Struct {
    var variable: String {
        willSet {
            variable  // before set 
            newValue  // after set,  immutable
        }
        didSet {
            oldValue  // before set, immutable
            variable  // after set
        }
    }
}

И то же самое вы можете сделать для любого другого сохраненного свойства, так что вы можете использовать его и для структурной переменной в вашем классе [ 1112]

class Class {
    var myStruct: Struct? {
        didSet {
            ...
        }
    }
}

Также вы можете, например, установить в наблюдателе переменную запись уведомления с определенным именем

didSet {
    NotificationCenter.default.post(name: Notification.Name("VariableSet"), object: nil)
}

, а затем вы можете добавить определенный класс в качестве наблюдателя для уведомления с этим именем

class Class {
    init() {
        NotificationCenter.default.addObserver(self, selector: #selector(variableSet), name: Notification.Name("VariableSet"), object: nil)
    }

    deinit {
        NotificationCenter.default.removeObserver(self, name: Notification.Name("VariableSet"), object: nil)
    }

    @objc func variableSet() {
        ...
    }
}
0
ответ дан Robert Dresler 17 January 2019 в 08:55
поделиться

Попробуйте это, сначала создайте структуру с переменной действия, а когда вы создаете объект структуры, задайте параметр действия для требуемого действия. напр.,

struct testStruct {
var action: (()->())?
var variable: String? {
    didSet {
        self.action?()
    }
}

}

А внутри вашего основного кода - главный класс

var testS = testStruct()
    testS.action = {
        print("Hello")
    }
    testS.variable = "Hi"

Когда вы установите testS.variabe = "Hi", он вызовет print ("Hello" )

0
ответ дан Βασίλης Δ. 17 January 2019 в 08:55
поделиться

Стандартные Swift « наблюдатели свойств » (didSet и willSet) предназначены для того, чтобы тип мог наблюдать изменения своих собственных свойств, но не для того, чтобы внешние объекты могли добавлять своих собственных наблюдателей. А KVO, который поддерживает внешних наблюдателей, предназначен только для dynamic и @objc свойств NSObject подклассов (как описано в Использование наблюдения значения ключа в Swift ).

Итак, если вы хотите, чтобы внешний объект наблюдал изменения внутри struct, как уже отмечали другие, вы должны создать свой собственный механизм наблюдения, используя Swift didSet и тому подобное. Но вместо того, чтобы реализовывать это самостоятельно, свойство за свойством, вы можете написать универсальный тип, чтобы сделать это для вас. Например,

struct Observable<T> {
    typealias Observer = String

    private var handlers: [Observer: (T) -> Void] = [:]

    var value: T {
        didSet {
            handlers.forEach { [110].value(value) }
        }
    }

    init(_ value: T) {
        self.value = value
    }

    @discardableResult
    mutating func observeNext(_ handler: @escaping (T) -> Void) -> Observer {
        let key = UUID().uuidString as Observer
        handlers[key] = handler
        return key
    }

    mutating func remove(_ key: Observer) {
        handlers.removeValue(forKey: key)
    }
}

Затем вы можете делать такие вещи, как:

struct Foo {
    var i: Observable<Int>
    var text: Observable<String>

    init(i: Int, text: String) {
        self.i = Observable(i)
        self.text = Observable(text)
    }
}

class MyClass {
    var foo: Foo

    init() {
        foo = Foo(i: 0, text: "foo")
    }
}

let object = MyClass()
object.foo.i.observeNext { [weak self] value in   // the weak reference is really only needed if you reference self, but if you do, make sure to make it weak to avoid strong reference cycle
    print("new value", value)
}

И затем, когда вы обновите свойство, например, как показано ниже, ваше закрытие обработчика наблюдателя будет вызвано: [ 1117]

object.foo.i.value = 42

Стоит отметить, что фреймворки, такие как Bond или RxSwift , предлагают такую ​​функциональность, а также многое другое.

0
ответ дан Rob 17 January 2019 в 08:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: