Я сделал свой список (массив объектов MarketIndex) в качестве наблюдаемого с помощью этого сайта:как сделать просмотр наблюдателя контроллера быстрым?
http://www.drewag.me/posts/swift-kvo-substitute-observable-variables
Это код Наблюдаемых из приведенного выше сайта, который я добавил к моей программе:
import Foundation
class Observable: NSObject {
typealias DidChangeHandler = (oldValue: Array<MarketIndex>?, newValue: Array<MarketIndex>) ->()
dynamic var value : Array<MarketIndex> {
didSet {
for (owner, handlers) in self.observers {
for handler in handlers {
handler(oldValue: oldValue, newValue: value)
}
}
}
}
init(_ value: Array<MarketIndex>) {
self.value = value
super.init()
}
func addObserverForOwner(owner: AnyObject, triggerImmediately: Bool, handler: DidChangeHandler) {
if let index = self.indexOfOwner(owner) {
// since the owner exists, add the handler to the existing array
self.observers[index].handlers.append(handler)
} else {
// since the owner does not already exist, add a new tuple with the
// owner and an array with the handler
self.observers.append(owner: owner, handlers: [handler])
}
if (triggerImmediately) {
// Trigger the handler immediately since it was requested
handler(oldValue: nil, newValue: self.value)
}
}
func removeObserversForOwner(owner: AnyObject) {
if let index = self.indexOfOwner(owner) {
self.observers.removeAtIndex(index)
}
}
// #pragma mark - Private Properties
var observers: [(owner: AnyObject, handlers: [DidChangeHandler])] = []
// #pragma mark - Private Methods
func indexOfOwner(owner: AnyObject) -> Int? {
var index : Int = 0
for (possibleOwner, handlers) in self.observers {
if possibleOwner === owner {
return index
}
index++
}
return nil
}
}
И вот код SocketManager, который имеет список объектов MarketIndex, которые станут заметными.
import Foundation
class SocketManager: WebSocketDelegate {
class var sharedInstance: SocketManager {
struct Static {
static var onceToken: dispatch_once_t = 0
static var instance: SocketManager? = nil
}
dispatch_once(&Static.onceToken) {
Static.instance = SocketManager()
}
return Static.instance!
}
var marketIndexList: Array<MarketIndex> = []
var indexesList: Observable = Observable([])
init() {
}
func getMarketIndexes(inputStream: String) {
// the marketIndexList will be updated from server every time that a value changes in the server
indexesList = Observable(marketIndexList)
println("\(indexesList.value)")
}
println("Market Index List Size: \(indexesList.value.count)")
}
}
Теперь я хочу, чтобы мой ViewController был наблюдателем для этого списка. Я добавил функцию addObserverForOwner в функцию viewDidLoad(), но она не меняется при каждом изменении моего списка. Вот код моего ViewController:
SocketManager - это класс, который имеет наблюдаемый индекс. Кроме того, SocketManager является Singleton. Функция notify() обновит значения меток и перезагрузит tableView моего ViewController.
class IndexViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
SocketManager.sharedInstance.indexesList.addObserverForOwner(self, triggerImmediately: true) { (oldValue, newValue) ->() in
self.marketIndexes = newValue
self.notify()
}
}
func notify() {
updateValues(marketIndexes)
tableView.reloadData()
}
}
Что я здесь делаю неправильно? Есть идеи?
Спасибо, ребята,
Спасибо, что ответит, Роб. Но 'marketIndexes' не обновляется каждый раз, когда мой массив обновляется из другого класса. Поэтому я не могу использовать didSet и перезагрузить таблицу. Моя проблема заключается в том, как обновить мои «marketIndexes» в моем ViewController, когда когда-либо обновлялся массив в другом классе (SocketManager). Кроме того, я вызвал мой метод 'getMarketIndexes' в методе, который получил сообщение из сокета. Таким образом, каждый раз, когда новое сообщение получает, я вызываю 'getMarketIndexes' и обновляю свой массив и делаю его Observable. – user2366997
Нет, ваш код не будет работать вообще. Кажется, вы работаете в предположении, что вы можете использовать этот шаблон Observable для переменной 'indexesList', а некоторые, как изменения в' marketIndexList' будут переводить на сообщения наблюдателей, управляемые 'indexesList'. Это не сработает. Вы должны использовать этот шаблон для самой переменной marketIndexList, если хотите, чтобы это работало. Устраните эту переменную 'indexesList' вообще. – Rob
Сначала это было то, что я хотел сделать. Я хотел сделать marketIndexList наблюдаемым с вышеописанным классом Observable, но это не сработало. Я написал 'marketIndexList = Observable (marketIndexList)', но я получил сообщение об ошибке: «MarketIndex» не идентичен «AnyObject» – user2366997