• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

ios - swift realm::IncorrectThreadException:从不正确的线程访问的 Realm

[复制链接]
菜鸟教程小白 发表于 2022-12-12 12:15:34 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

我创建了一个名为"file"的模型,使用 Realm Browser 看起来还不错: Realm Browser

但是当我使用模型时,它会返回错误: libc++abi.dylib: 以未捕获的 Realm 类型异常终止::IncorrectThreadException: Realm 从不正确的线程访问。

在我的代码中,我在每个需要添加/更新的地方创建 Realm 对象:

private var allFiles : Results<File>!

private var downloadingFiles : Results<File>! {
    return self.allFiles.filter("completed = false")
}

private var downloadedFiles : Results<File>! {
    return self.allFiles.filter("completed = true")
}

private var downloading = false

private var request: Alamofire.Request?

func download() {

    let fileRealm = try! Realm()
    allFiles = fileRealm.objects(File).sorted("updatedAt")

    downloadFile()
}

private func downloadFile() {

    if !self.downloading, let file = self.downloadingFiles.first where !file.completed {

        self.reqForDownload(file)
    }
}

private func reqForDownload(file: File) -> Void {

    downloading = true

    request = Alamofire
        .download(.GET, file.url, destination: { (url, response) -> NSURL in

            return NSURL(fileURLWithPath: file.filePath)

        })
        .progress { [unowned self](bytesRead, totalBytesRead, totalBytesExpectedToRead) in
            dispatch_async(dispatch_get_main_queue(), {
                let variable = Float(totalBytesRead)/Float(totalBytesExpectedToRead)
                debugPrint(variable)
            })
        }
        .response { [unowned self](request, response, data, error) in
            if let error = error {

                dispatch_async(dispatch_get_main_queue(), {
                    let fileRealm = try! Realm()
                    try! fileRealm.write({
                        file.completed = false
                    })
                    self.allFiles = fileRealm.objects(File).sorted("updatedAt")
                })

                if error.code == NSURLErrorCancelled {
                    debugPrint("Canceled download")
                }

            } else {
                debugPrint("Downloaded file successfully")

                dispatch_async(dispatch_get_main_queue(), {
                    let fileRealm = try! Realm()
                    try! fileRealm.write({
                        file.completed = true
                    })
                    self.allFiles = fileRealm.objects(File).sorted("updatedAt")
                })
            }

            self.downloading = false 
    }
}

我是 Realm 的新手,但我知道 Realm 不是线程安全的,所以我尝试使用主线程中的对象作为我的代码,但错误仍然出现。请高人帮帮我,谢谢。

我已将代码更新为@TimOliver 的suggest ,但它仍然响应相同的错误。新代码如下:

private var allFiles : Results<File>!

private var downloadingFiles : Results<File>! {
    return self.allFiles.filter("completed = false")
}

private var downloadedFiles : Results<File>! {
    return self.allFiles.filter("completed = true")
}

private var downloading = false

private var request: Alamofire.Request?

func download() {

    let fileRealm = try! Realm()
    allFiles = fileRealm.objects(File).sorted("updatedAt")

    downloadFile()
}

private func downloadFile() {

    if !self.downloading, let file = self.downloadingFiles.first where !file.completed {

        self.reqForDownload(file)
    }
}

private func reqForDownload(file: File) -> Void {

    downloading = true

    request = Alamofire
        .download(.GET, file.url, destination: { (url, response) -> NSURL in

            return NSURL(fileURLWithPath: file.filePath)

        })
        .progress { [unowned self](bytesRead, totalBytesRead, totalBytesExpectedToRead) in
            dispatch_async(dispatch_get_main_queue(), {
                let variable = Float(totalBytesRead)/Float(totalBytesExpectedToRead)
                debugPrint(variable)
            })
        }
        .response { [unowned self](request, response, data, error) in
            if let error = error {

                let fileRealm = try! Realm()
                    try! fileRealm.write({
                        file.completed = false
                    })
                    self.allFiles = fileRealm.objects(File.self).sorted("updatedAt")

                if error.code == NSURLErrorCancelled {
                    debugPrint("Canceled download")
                }

            } else {
                debugPrint("Downloaded file successfully")

                let fileRealm = try! Realm()
                    try! fileRealm.write({
                        file.completed = true
                    })
                    self.allFiles = fileRealm.objects(File.self).sorted("updatedAt")
            }

            self.downloading = false 
    }
}



Best Answer-推荐答案


就像我在评论中问的那样,如果你设置了异常断点,你可以准确地看到哪一行代码触发了 Realm 异常,这样你就可以跟踪 Realm 事务发生在哪个线程中,以及哪些对象正在交互用它。

如果我没记错的话,我相信在该方法的 .response 部分中调用的闭包默认不会在主线程上调用,但是您正在尝试修改 file 明确在主线程上查询的对象。

没有强制其中的每个闭包在主线程上调用,更合适的是 primary key file 对象中的属性,直接持有对主键值的引用,然后在需要更新时直接查询 file 对象的线程本地版本(即使用 Realm.object(ofType: primaryKey 方法。

关于ios - swift realm::IncorrectThreadException:从不正确的线程访问的 Realm ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40201917/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap