Стандартные Swift « наблюдатели свойств » (didSet
и willSet
) предназначены для того, чтобы тип мог наблюдать изменения своих собственных свойств, но не для того, чтобы внешние объекты могли добавлять своих собственных наблюдателей. А KVO, который поддерживает внешних наблюдателей, предназначен только для dynamic
и @objc
свойств NSObject
подклассов (как описано в Использование наблюдения значения ключа в Swift ).
Итак, если вы хотите, чтобы внешний объект наблюдал изменения внутри struct
, как уже отмечали другие, вы должны создать свой собственный механизм наблюдения, используя Swift didSet
и тому подобное. Но вместо того, чтобы реализовывать это самостоятельно, свойство за свойством, вы можете написать универсальный тип, чтобы сделать это для вас. Например,
struct Observable {
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
var text: Observable
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 , предлагают такую функциональность, а также многое другое.
Все файлы ASPX должны только содержать
Это - файл маркера, сгенерированный инструментом перед компиляцией, и не должно быть удалено!
Удалите все в своей папке мусорного ведра и опубликуйте сеть снова. Удостоверьтесь, что Вы берете файлы из каталога, где Вы сделали публикацию.
Удостоверьтесь, что Вы копируете .compiled
файлы, содержавшиеся в папке мусорного ведра также.
Для записи я забыл копировать эти ".compiled" файлы (документация MSDN: Обработка Файла Во время Предварительной компиляции ASP.NET):
Для исполняемых файлов в веб-приложении ASP.NET, блоках компилятора и файлах с .compiled расширением файла. Имя сборки сгенерировано компилятором. .compiled файл не содержит исполняемый код. Вместо этого это содержит только информацию, что ASP.NET должен найти соответствующий блок.
После того, как предварительно скомпилированное приложение развертывается, ASP.NET использует блоки в папке Bin для обработки запросов. Вывод перед компиляцией включает .aspx или .asmx файлы как заполнители для страниц. Файлы заполнителя не содержат кода. Они существуют только, чтобы позволить вызывать ASP.NET для определенного запроса страницы и так, чтобы полномочия файла могли быть установлены ограничить доступ к страницам.