Realm - Realm Доступ к неверной ветке Swift
Я новичок в Realm и получаю сообщение об ошибке "Доступ к Realm из неверной цепочки". Я прочитал, что нужно получить доступ к данным в той же области, из которой они были получены. Однако я получаю эту ошибку после успешного доступа к объекту. Вот некоторый код:
func retrieveApplicationData(completionBlock: (Results<Application>, NSError?) -> Void) {
let realm = try! Realm()
let applications = realm.objects(Application)
if applications.count > 0 {
completionBlock(applications, nil)
}
}
Этот метод вызывает метод, который создает массив приложений, используя: let array = Array(results)
Затем я передаю это в метод, который устанавливает массив:
func setApplicationItems(items: [Application]) {
applications = items
print(applications)
}
В вышеупомянутом методе я распечатываю массив, и это прекрасно работает. Однако позже в цикле вызывается метод tableViewDatasource cellForRowAtIndexPath. Здесь я пытаюсь использовать массив приложений, но приложение вылетает с ошибкой "неверный поток". Вот метод:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
print("\(applications)")
let cell = ApplicationTableViewCell(style: .Subtitle, reuseIdentifier: nil)
let application = applications[indexPath.row]
cell.configureCell(application)
return cell
}
Как вы можете видеть, я добавил оператор print в вышеуказанном методе. Когда я пытаюсь распечатать массив приложений здесь, я получаю сбой.
Почему я могу распечатать это в методе, который устанавливает это, но здесь это терпит крах? Это потому что cellForRowAtIndexPath
вызывается в основном потоке? И если так, как я могу обновить свой tableView
в этом случае? Приветствия.
========
Редактировать:
Когда я делаю следующее в cellForRowAtIndexPath
Я получаю пустой результат:
let realm = try! Realm()
let applicationsB = realm.objects(Application)
Изменить 2:
Я занимаюсь экономией в закрытии. Я попытался передать его обратно в основной поток, используя dispatch_async
когда данные вернулись, и он все еще падал. Однако я перенес это dispatch_async
непосредственно перед вызовом self.tableView.reloadData(). Теперь это не дает сбой, что хорошо, но данные не всегда доступны. Если я замедляю его, используя точки останова, я получаю данные обратно. Однако данных не будет, если я просто позволю им работать. Есть ли способ узнать, когда данные, сохраненные в фоновом потоке, доступны в основном потоке?
Вот код, который я использую:
dispatch_async(dispatch_get_main_queue()) {
let realm = try! Realm()
realm.refresh()
let applicationsB = realm.objects(Application)
let array = Array(applicationsB)
self.tableViewDataSource.setApplicationItems(array as! [Application])
self.tableView.reloadData()
}
Данные не всегда есть.
Изменить 3:
Теперь я завернул метод сохранения в dispath_async(dispath_get_main_queue())
и работает нормально
dispatch_async(dispatch_get_main_queue()) {
let realm = try! Realm()
try! realm.write() {
let applications = data.map({ (object) -> Application in
return Application(applicationID: object.applicationID, contact: "", state: "", jobBoard: object.jobBoard, salary: object.salary, title: object.title, location: "")
})
for application in applications {
print(application)
realm.add(application)
}
//try! realm.commitWrite()
completionBlock(true, nil)
}
1 ответ
Редактировать:
Пожалуйста, прочитайте комментарий от bdash ниже. Хотя это работает, на самом деле это только случайно. Оставив здесь ответ, чтобы другие не попробовали то же самое.
Следующий код работал, но не правильно!!!:
Так что мне удалось заставить его работать. Сначала я остановил приложение и на экране появился добавленный код, который загрузил данные. Это работало нормально. Итак, я знал, что данные были в базе данных. Однако я хотел сохранить данные и сразу же использовать их.
Чтобы добиться этого, мне нужно было добавить следующее try! realm.commitWrite()
внутри моего realm.write() { }
блок. Полный метод ниже:
try realm.write() {
let applications = data.map({ (object) -> Application in
return Application(applicationID: object.applicationID, contact: "", state: "", jobBoard: object.jobBoard, salary: object.salary, title: object.title, location: "")
})
for application in applications {
print(application)
realm.add(application)
}
try! realm.commitWrite() // *NOTE* Here is the code I added.
completionBlock(true, nil)
}
После того как я добавил commitWrite(), я смог позже выполнить выборку в основном потоке следующим образом:
dispatch_async(dispatch_get_main_queue()) {
let realm = try! Realm()
realm.refresh()
let applicationsB = realm.objects(Application)
let array = Array(applicationsB)
self.tableViewDataSource.setApplicationItems(array as! [Application])
self.tableView.reloadData()
}