在主线程中使用后台线程的快速领域插入数组 [英] swift realm insert array in background thread use in main
问题描述
我有一组通过rest响应接收的对象,我想将它们插入背景线程中的realm db中,并在 main 线程的uicollectionview中使用.收到休息的响应后,我将调用回调函数,并将数组插入后台线程中的db中.当我尝试访问在后台插入的对象的主线程属性时出现的问题,我得到了异常(请参见下文),我认为这是由于尚未插入对象而引起的
I have an array of objects received via rest response, which I want to insert into realm db in a background thread and use in a uicollectionview in main thread. As soon as I receive response from rest, I call callback function and insert array into db in a background thread. The problem when I am trying to access in main thread property of object being inserted in background I'm getting exception (see below) which I assume because of object not yet inserted
由于未捕获的异常"RLMException"而终止应用程序,原因:从错误的线程访问了领域.
Terminating app due to uncaught exception 'RLMException', reason: 'Realm accessed from incorrect thread.
模型
class User : Object, Mappable {
dynamic var firstName: String?
dynamic var lastName: String?
required convenience init?(map: Map){
self.init()
}
func mapping(map: Map) {
firstName <- map["firstName"]
lastName <- map["lastName"]
}
}
插入后台线程...
DispatchQueue.global().async {
let realm = try! Realm()
try! realm.write {
realm.add(users)
}
}
在用户界面中呈现...
Rendering in UI...
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = self.collectionView.dequeueReusableCell(withReuseIdentifier: "MyCell", for: indexPath) as! UserViewCell
let user = users[indexPath.row]
cell.firstName.text = user.firstName
cell.lastName.text = user.lastName
}
请注意,访问firstName或lastName时会发生异常.
Please note that exception occur either on accessing firstName or lastName.
请让我知道我在做什么错
Please let me know what I'm doing wrong here
推荐答案
最简单的解决方案是在主线程上创建对Realm实例的新引用,并使用新创建的引用从领域中获取所有用户.从同一线程访问领域.
The easiest solution is to create a new reference to your Realm instance on the main thread and fetch all users from realm using the newly created reference, so you will be accessing realm from the same thread.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = self.collectionView.dequeueReusableCell(withReuseIdentifier: "MyCell", for: indexPath) as! UserViewCell
let users = try! Realm().objects(User.self)
let user = users[indexPath.row]
cell.firstName.text = user.firstName
cell.lastName.text = user.lastName
}
另一种解决方案是使用 ThreadSafeReference
对象将 users
数组从后台线程传递到主线程.但是,如果 users
的类型为 Results
,则只能为您的 users
集合创建单个 ThreadSafeReference
List
的列表.如果类型为 Results< User>
,请参见以下假定 users
的代码.
Another solution is to use a ThreadSafeReference
object to pass the users
array from the background thread to the main thread. However, you can only create a single ThreadSafeReference
to your collection of users
if the type of users
is either Results
of List
. See below code assuming users
if of type Results<User>
.
var usersRef: ThreadSafeReference<Results<User>>?
DispatchQueue.global().async {
autoreleasepool{
let realm = try! Realm()
try! realm.write {
realm.add(users)
}
usersRef = ThreadSafeReference(to: users)
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = self.collectionView.dequeueReusableCell(withReuseIdentifier: "MyCell", for: indexPath) as! UserViewCell
let realm = try! Realm()
guard let usersRef = usersRef, let users = realm.resolve(usersRef) else {return}
let user = users[indexPath.row]
cell.firstName.text = user.firstName
cell.lastName.text = user.lastName
}
这篇关于在主线程中使用后台线程的快速领域插入数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!