i have array of objects received via rest response, want insert realm db in background thread , use in uicollectionview in main thread. receive response rest, call callback function , insert array db in background thread. problem when trying access in main thread property of object being inserted in background i'm getting exception (see below) assume because of object not yet inserted
terminating app due uncaught exception 'rlmexception', reason: 'realm accessed incorrect thread.
the model
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"] } }
inserting in background thread...
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 }
please note exception occur either on accessing firstname or lastname.
please let me know i'm doing wrong here
the easiest solution create new reference realm instance on main thread , fetch users realm using newly created reference, accessing realm 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 }
another solution use threadsafereference
object pass users
array background thread main thread. however, can create single threadsafereference
collection of users
if type of users
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 }
Comments
Post a Comment