2016-11-21 2 views
0

Ich versuche, einen Fortschritt Eigenschaft auf meinem Realm Objekt zu aktualisieren, die wie folgt aussieht:Aktualisierung Upload-Fortschritt auf Realm Objekt

class Upload: Object { 

    dynamic var name: String = "" 
    dynamic var key: String = "" 
    dynamic var localIdentifier:String = "" 
    dynamic var data: NSData? = nil 
    dynamic var albumKey: String = "" 
    dynamic var isUploading: Bool = false 
    dynamic var status: String = "" 
    dynamic var progress: Float = 0.0 
    dynamic var urlString: String = "" 
    let isVideo = RealmOptional<Bool>() 

    override static func primaryKey() -> String? { 
     return "localIdentifier" 
    } 
} 

Der Rahmen i für den Upload einen Fortschritt Update geben bin mit jedem 0,5 Sekunden ca. Der Rückruf sieht wie folgt aus:

task.observe(.progress) { snapshot in 
      let float = Float(snapshot.progress!.fractionCompleted) 
      self.update(progress: float, forUpload: upload) 
     } 

fileprivate func update(progress: Float, forUpload upload: Upload) { 
     do { 
      let realm = try Realm() 
      let u = Upload() 
      u.progress = progress 
      u.localIdentifier = upload.localIdentifier 
      try realm.write { 
       realm.add(u, update: true) 
      } 
     } catch { 
      print(error) 
     } 
    } 

Mit dem obigen Code, es stürzt immer wieder ab und gibt mir ein ‚RLMException‘ Grund: ‚Das Reich ist bereits in einer Schreibtransaktion‘.

I dont‘wissen, ob dieser Fehler tritt auf, weil ich habe 3 simultane Downloads ausgeführt wird, oder weil das Objekt in Frage beschäftigt ist (ich dachte, dass ein neues Objekt erstellt es mit dem gleichen Primärschlüssel zuweisen würde dies lindern?)

Also meine Frage ist, wie gehe ich darüber? Versuche ich etwas zu tun, das etwas außerhalb von dem liegt, für das du Realm verwenden würdest?

+0

Was ist der Grund dafür, jedes Mal, wenn 'update()' aufgerufen wird, ein ganz neues "Upload" -Objekt zu erstellen? Da Sie ein vorhandenes "Upload" -Objekt übergeben, würde ich denken, dass es sinnvoller ist, einfach den neuen Wert von 'progress' in den vorhandenen' upload' zu schreiben. – AustinZ

Antwort

1

Unter der Annahme, dass läuft synchron in einem separaten Thread, update läuft auf dem gleichen Thread, so dass Sie zwei auf einmal ausgeführt bekommen können. Die einfachste Sache zu tun wäre, um es zu zwingen auf dem Haupt-Thread ausgeführt wird:

task.observe(.progress) { snapshot in 
      let float = Float(snapshot.progress!.fractionCompleted) 
      DispatchQueue.main.sync { 
       self.update(progress: float, forUpload: upload) 
      } 
     } 

Ich vermute auch, dass Sie eine neue Upload Instanz jedes Mal sind die Schaffung weil sie sonst von verschiedenen Threads zugegriffen werden. Wenn Sie den Hauptthread ausführen, können Sie den Fortschritt nur für die eine Instanz aktualisieren.

+0

Das Versenden an eine serielle Hintergrundwarteschlange würde den gleichen Effekt haben, ohne den Hauptthread zu blockieren. – jpsim

Verwandte Themen