2017-09-10 4 views
0

I ont un tableau d'objets reçus par réaction de repos, ce que je veux insérer dans domaine db dans un fil de fond et l'utilisation dans un uicollectionview dans principal fil. Dès que je reçois une réponse de repos, j'appelle la fonction de rappel et insère un tableau dans db dans un thread d'arrière-plan. Le problème quand je suis en train d'accéder au principal propriété de fil d'objet inséré en arrière-plan, je reçois exception (voir ci-dessous) que je suppose que l'objet pas encore insérématrice d'insertion de domaine rapide lors de l'utilisation du fil de fond dans principal

Mettre fin application en raison de uncaught exception 'RLMException', raison: 'Domaine accessible à partir d'un thread incorrect.

Le modèle

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"] 
    } 
} 

Insertion dans un thread d'arrière-plan ...

DispatchQueue.global().async { 
    let realm = try! Realm() 
    try! realm.write { 
    realm.add(users) 
    } 
} 

rendu dans l'interface utilisateur ...

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 
} 

S'il vous plaît noter que exception se soit accéder à firstName ou lastName.

S'il vous plaît laissez-moi savoir ce que je fais mal ici

+1

Avez-vous pensé à utiliser un notificationToken? – EpicPandaForce

+0

C'est la seule chose à laquelle je pensais mais je ne savais pas si c'était une bonne idée. – mihatel

+0

C'est ce que le jeton de notification de Realm est pour – EpicPandaForce

Répondre

1

La solution la plus simple est de créer une nouvelle référence à votre instance de royaume sur le thread principal et chercher tous les utilisateurs du monde en utilisant la référence nouvellement créée, de sorte que vous accédera au domaine depuis le même 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 
} 

Une autre solution consiste à utiliser un objet ThreadSafeReference pour passer le tableau users à partir du fil de fond pour le fil conducteur. Cependant, vous ne pouvez créer qu'un seul ThreadSafeReference à votre collection de users si le type users est Results ou List. Voir ci-dessous le code en supposant users si de 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 
}