gpt4 book ai didi

swift - 结合 Realm 执行异步串行请求的问题

转载 作者:行者123 更新时间:2023-11-28 08:26:14 26 4
gpt4 key购买 nike

我想结合 Realm 执行一组串行异步请求。

我要处理的请求集用于更新远程服务器,并由包含对象类型和本地 uuid 的结构数组确定。相关对象从 Realm 数据库中获取,随后使用 Alamofire 写入服务器。

但是,获取 Realm 对象会导致错误(Realm 从不正确的线程访问)。

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 请求,OperationQueueDispatchSemaphore 结合使用。

    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 相同的线程上执行?

如果有任何解决这些问题的想法,我将不胜感激。

最佳答案

Realm 和Realm 对象是线程限制的。您应该在每个线程上检索新的 Realm 实例。不要跨其他线程传递 Realm 实例。

似乎主线程因等待信号量而停止。然后在主线程上执行 Alamofire 回调。所以 semaphore.signal() 永远不会被调用,因为主线程停止了。 Alamofire 的 response* 方法可以指定 queue 回调被调用。

关于swift - 结合 Realm 执行异步串行请求的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39898969/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com