我想與Realm一起執行一組串行異步請求。與Realm一起執行異步串行請求的問題
我想要處理的一組請求用於更新遠程服務器,並根據包含對象類型和本地uuid的結構數組來確定。相關對象從Realm數據庫中提取,然後使用Alamofire寫入服務器。
但是,獲取Realm對象會導致錯誤(Realm accessed from incorrect thread
)。
func performAsyncRequest<T: Object>(objectType: T.Type, uuid: String, failure fail: (()->Void)? = nil, success succeed: @escaping() -> Void)->Void {
let realm = try! Realm()
let dataObject = realm.objects(objectType).filter("uuid == %@", uuid).first!
let parameters = self.toJson(item: dataObject)
// ** The Realm error occurs when the Alamofire request is performed **
let urlRequest = self.getRequest(objectType: T.self, with: parameters)
self.alamoFireManager.request(urlRequest) // Perform POST request
.responseString { response in
if let status = response.response?.statusCode {
if status >= 200 && status <= 299 {
succeed() // Is not reached in combination with DispatchSemaphore
} else if status >= 400 && status <= 499 {
fail?() // Is not reached in combination with DispatchSemaphore
}
}
}
}
編輯:下面的代碼是下面的答案(其中與串行Alamofire請求先前問題解決)後編輯。
爲了順序執行Alamofire請求,OperationQueue
與DispatchSemaphore
組合使用。
let operationQueue = OperationQueue()
var operation: Operation!
for requestData in requests { // requestData is a struct with the object Type and a uuid
switch requestData.objectType {
case is Object1.Type:
operation = BlockOperation(block: {
let semaphore = DispatchSemaphore(value: 0)
self.performAsyncRequest(objectType: Object1.self, uuid: requestData.uuid, failure: { error in
semaphore.signal()
}) {
semaphore.signal()
}
semaphore.wait()
})
case is Object2.Type:
// ... same as for Object1 but now for Object2
// .. and so on for other Objects
}
operationQueue.addOperation(operation)
}
如下面的答案所示,由於Realm是線程受限的,所以出現錯誤。但是,我不清楚爲什麼Realm實例會通過不同的線程傳遞。
有了異常斷點,我確定錯誤發生在線程Queue: NSOperationQueue 0x… (QOS: UTILITY) (serial)
上。這是與執行BlockOperation
(從而獲取Realm對象的位置)不同的線程。爲什麼BlockOperation
中的方法不能在NSOperationQueue
的同一線程上執行?
我將不勝感激任何想法來處理這些問題。
rxSwift可以是一個更好的方法https://github.com/ReactiveX/RxSwift – StrawHara
這是一個很好的建議,我通過所有文檔工作。但是,問題仍然是Realm是線程受限的,在使用RxSwift時也需要保證。 – Taco
看看這個其他問題,我們可能在這裏有一個重複:http://stackoverflow.com/q/28646323/563802 – xpereta