我创建了一个名为"file"的模型,使用 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-推荐答案 strong>
就像我在评论中问的那样,如果你设置了异常断点,你可以准确地看到哪一行代码触发了 Realm 异常,这样你就可以跟踪 Realm 事务发生在哪个线程中,以及哪些对象正在交互用它。
如果我没记错的话,我相信在该方法的 .response 部分中调用的闭包默认不会在主线程上调用,但是您正在尝试修改 file 明确在主线程上查询的对象。
没有强制其中的每个闭包在主线程上调用,更合适的是 primary key file 对象中的属性,直接持有对主键值的引用,然后在需要更新时直接查询 file 对象的线程本地版本(即使用 Realm.object(ofType: primaryKey 方法。
关于ios - swift realm::IncorrectThreadException:从不正确的线程访问的 Realm ,我们在Stack Overflow上找到一个类似的问题:
https://stackoverflow.com/questions/40201917/
|