1

我是 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
}

如您所见,我在上述方法中添加了一条打印语句。当我尝试在这里打印应用程序数组时,我遇到了崩溃。

为什么我可以在设置它的方法中打印出来,但是在这里它崩溃了?是因为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:

我现在已经将 save 方法包装在 a 中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)

        }
4

1 回答 1

0

编辑:

请阅读下面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()
        }
于 2016-06-27T15:21:41.463 回答