2016-11-21 8 views
0

Я пытаюсь обновить свойство прогресса на моем объекте Realm, который выглядит следующим образом:Обновление на Realm объекта

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

Каркас я использую дать обновление прогресса для загрузки каждый .5 секунд ок. Обратный вызов выглядит следующим образом:

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) 
     } 
    } 

С выше коде, он держит сбой и дает мне «RLMException», причина: "Realm уже в транзакции записи.

Я «не знает, происходит ли это ошибка, потому что у меня есть 3 одновременные загрузки работают, или потому, что рассматриваемый объект занят (я думал, что создание нового объекта назначая его с таким же первичным ключом облегчил бы это?)

Так что мой вопрос в том, как мне это сделать? Я пытаюсь сделать что-то, что немного за пределами того, для чего вы бы использовали мир?

+0

В чем причина создания целого нового объекта 'Upload' каждый раз, когда вызывается' update() '? Поскольку вы проходите в существующем объекте «Загрузить», я думаю, что имеет смысл просто написать новое значение «progress» в существующую «загрузку». – AustinZ

ответ

1

Исходя из предположения, что task.observe работает синхронно в отдельном потоке, update работает в одном потоке, поэтому вы можете сразу запустить два режима. Проще всего было бы сделать, чтобы заставить запустить его на главную теме:

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

Я также предполагаю, что вы создаете новую Upload экземпляра каждый раз, потому что в противном случае они будут доступны из разных потоков. Если вы запускаете основной поток, вы можете просто обновить ход одного экземпляра.

+0

Отправка на фоновый последовательный порядок будет иметь тот же эффект, не блокируя основной поток. – jpsim