2016-10-23 8 views
2

からアクセスレルム私は「ファイル」という名前のモデルを作成しました、そしてそれはレルムブラウザでOKになります。 Realm Browser迅速分野:: IncorrectThreadException:間違ったスレッド

が、私はモデルを使用する場合、それはエラーが返されます:

private var allFiles : Results<File>! 

private var downloadingFiles : Results<File>! { 
    return self.allFiles.filter("completed = false") 
} 

private var downloadedFiles : Results<File>! { 
    return self.allFiles.filter("completed = true") 
} 

private var downloading = false 

private var request: Alamofire.Request? 

func download() { 

    let fileRealm = try! Realm() 
    allFiles = fileRealm.objects(File).sorted("updatedAt") 

    downloadFile() 
} 

private func downloadFile() { 

    if !self.downloading, let file = self.downloadingFiles.first where !file.completed { 

     self.reqForDownload(file) 
    } 
} 

private func reqForDownload(file: File) -> Void { 

    downloading = true 

    request = Alamofire 
     .download(.GET, file.url, destination: { (url, response) -> NSURL in 

      return NSURL(fileURLWithPath: file.filePath) 

     }) 
     .progress { [unowned self](bytesRead, totalBytesRead, totalBytesExpectedToRead) in 
      dispatch_async(dispatch_get_main_queue(), { 
       let variable = Float(totalBytesRead)/Float(totalBytesExpectedToRead) 
       debugPrint(variable) 
      }) 
     } 
     .response { [unowned self](request, response, data, error) in 
      if let error = error { 

       dispatch_async(dispatch_get_main_queue(), { 
        let fileRealm = try! Realm() 
        try! fileRealm.write({ 
         file.completed = false 
        }) 
        self.allFiles = fileRealm.objects(File).sorted("updatedAt") 
       }) 

       if error.code == NSURLErrorCancelled { 
        debugPrint("Canceled download") 
       } 

      } else { 
       debugPrint("Downloaded file successfully") 

       dispatch_async(dispatch_get_main_queue(), { 
        let fileRealm = try! Realm() 
        try! fileRealm.write({ 
         file.completed = true 
        }) 
        self.allFiles = fileRealm.objects(File).sorted("updatedAt") 
       }) 
      } 

      self.downloading = false 
    } 
} 

私はレルムのために新たなんだけど、私はレルムはスレッドセーフではない知っているので、私は」:私のコードでは libc++abi.dylib: terminating with uncaught exception of type realm::IncorrectThreadException: Realm accessed from incorrect thread.

、私は私のニーズは/更新を追加したすべてのレルムのオブジェクトを作成します私は試しました私のコードとしてメインスレッドのオブジェクトを使用するが、エラーはまだ現れた。誰か助けてください、ありがとう。

@ TimOliverのsuggestとしてコードを更新しましたが、それでも同じエラーが返されます。以下のように新しいコード:

private var allFiles : Results<File>! 

private var downloadingFiles : Results<File>! { 
    return self.allFiles.filter("completed = false") 
} 

private var downloadedFiles : Results<File>! { 
    return self.allFiles.filter("completed = true") 
} 

private var downloading = false 

private var request: Alamofire.Request? 

func download() { 

    let fileRealm = try! Realm() 
    allFiles = fileRealm.objects(File).sorted("updatedAt") 

    downloadFile() 
} 

private func downloadFile() { 

    if !self.downloading, let file = self.downloadingFiles.first where !file.completed { 

     self.reqForDownload(file) 
    } 
} 

private func reqForDownload(file: File) -> Void { 

    downloading = true 

    request = Alamofire 
     .download(.GET, file.url, destination: { (url, response) -> NSURL in 

      return NSURL(fileURLWithPath: file.filePath) 

     }) 
     .progress { [unowned self](bytesRead, totalBytesRead, totalBytesExpectedToRead) in 
      dispatch_async(dispatch_get_main_queue(), { 
       let variable = Float(totalBytesRead)/Float(totalBytesExpectedToRead) 
       debugPrint(variable) 
      }) 
     } 
     .response { [unowned self](request, response, data, error) in 
      if let error = error { 

       let fileRealm = try! Realm() 
        try! fileRealm.write({ 
         file.completed = false 
        }) 
        self.allFiles = fileRealm.objects(File.self).sorted("updatedAt") 

       if error.code == NSURLErrorCancelled { 
        debugPrint("Canceled download") 
       } 

      } else { 
       debugPrint("Downloaded file successfully") 

       let fileRealm = try! Realm() 
        try! fileRealm.write({ 
         file.completed = true 
        }) 
        self.allFiles = fileRealm.objects(File.self).sorted("updatedAt") 
      } 

      self.downloading = false 
    } 
} 
+0

私たちはこれを釘付けにするためにさらに詳しい情報が必要になると思います。例外ブレークポイント(http://stackoverflow.com/questions/17802662/exception-breakpoint-in-xcode)を追加して、コードのどこがトリガされているかを教えてください。 – TiM

答えて

2

私はコメントで尋ねたようにあなたは、例外ブレークポイントを設定した場合、あなたはあなたがスレッドでレルムトランザクションを追跡できるように、コードのどの行がレルムの例外をトリガしている正確に見ることができますどのオブジェクトがそれと対話しているのかが分かります。

私が正しくリコール、私はしかし、あなたは間違いなく上を問い合わせたfileオブジェクトを変更しようとしている、その方法の.response部分で呼び出さ閉鎖は、デフォルトではメインスレッドで呼び出されないと考えていますメインスレッド。

primary keyオブジェクトには、fileオブジェクトのプロパティを持ち、プライマリキー値への参照を直接保持してから、直接オブジェクトのクエリを実行するのが適切ですあなたがRealm.object(ofType: primaryKey:)メソッドを使用して、すなわち(それを更新する必要がある場合fileオブジェクトのローカルバージョンを通します。.response()閉鎖中

+0

私の遅い返事には申し訳ありません。私がテストをしたあなたの言葉通り、あなたは正しいです。 '.download'と '.response'部分はメインスレッドにはありませんが、Realmオブジェクトを使っています。あなたの親切な助けに感謝します。 – Raniys

1

self.allFiles = fileRealm.objects(File.self).sorted("updatedAt")は、サブスレッドをexcutedた。後でメインスレッドでself.allFilesにアクセスするので、それがクラッシュしていました。

Results instances are live, auto-updating views into the underlying data, which means results never have to be re-fetched. They always reflect the current state of the Realm on the current thread, including during write transactions on the current thread.

https://realm.io/docs/swift/latest/#auto-updating-results

したがって、allFilesを再フェッチする必要はありません。トランザクションがコミットされました。allFilesが自動的に更新されます。