信号量同步请求 Swift4 永远停止
Semaphore to sync request Swift4 stopped forever
我需要来自网络服务的同步请求,所以我使用 sempahore:
class func syncProducts() {
print("syncProducts() 1")
let idsLocal = getProductsIds()
let semaphore = DispatchSemaphore(value: 0)
var idsCloud : [Int] = []
print("Getting cloud ids... 1")
OdooService.getProductsIds { (params: [Int]) in
print("SuccessBlock size ids: \(params.count) 1")
idsCloud = params
semaphore.signal()
}
semaphore.wait()
print("Depois do GetproductsIds: 1")
}
但在这个例子中,应用程序永远保持锁定状态!请求永无止境。这是我从网络服务器请求数据的功能,如果是的话,returns 到成功块。
static func getProductsIds(successBlock: @escaping (_ params: [Int]) -> Void) {
// check odoo auth
let dispatch = DispatchGroup()
if( OdooAuth.uid == 0 ) {
print("Odoo offline, tentando reconectar...")
dispatch.enter()
OdooAuth.reconnect(successBlock: { params in
print("Reconectado com sucesso...")
dispatch.leave()
}, failureBlock: { params in
print("Falha no ReAuth")
return
})
}
print("Start request from Odoo...")
let fieldsProducts = ["id"]
let options = [ "fields": fieldsProducts] as [String : Any]
var idsList : [Int] = []
let params = [OdooAuth.db, OdooAuth.uid, OdooAuth.password,"product.template","search_read",[],options] as [Any]
AlamofireXMLRPC.request(OdooAuth.host2, methodName: "execute_kw", parameters: params).responseXMLRPC {
(response: DataResponse<XMLRPCNode>) -> Void in
switch response.result {
case .success( _):
print("Success to get Ids")
let str = String(data: response.data!, encoding: String.Encoding.utf8) as String!
let options = AEXMLOptions()
let xmlDoc = try? AEXMLDocument(xml: (str?.data(using: .utf8))!,options: options)
//print(xmlDoc!.xml)
for child in (xmlDoc?.root["params"]["param"]["value"]["array"]["data"].children)! {
for childValue in child["struct"].children {
let id = childValue["value"]["int"].value!
idsList.append(Int(id)!)
//print("Id: \(id)")
}
}
successBlock(idsList)
break
case .failure(let error):
print("Error to get Ids: \(error.localizedDescription)")
break
} // fim switch
} // fim request
} // fim getProductsIds
我不知道信号量是否是执行此操作的最佳方式,但我需要同步请求!我试过像在 reauth 中那样使用 DispatchGroup(),但也不起作用。
我认为死锁是在主线程上调用 getProductsIds
回调的结果,主线程被信号量阻塞。据我所知,默认情况下 Alamofire 在主线程上调度回调,我希望 AlamofireXMLRPC 就是这种情况,因为它是 Alamofire 的包装器。
我强烈建议在异步操作期间不要阻塞主线程。
但是,如果出于任何非常好的原因您不能这样做,您将需要确保回调不会在主调度队列中调度(因为主调度队列被阻塞等待信号) . Alamofire 本身有一个 response
重载,允许指定 运行 回调的 DispatchQueue
对象。似乎 AlamofireXMLRPC 也有一个,所以我会尝试利用它并更改
AlamofireXMLRPC.request(OdooAuth.host2, methodName: "execute_kw", parameters: params)
.responseXMLRPC {
// process result
}
至:
AlamofireXMLRPC.request(OdooAuth.host2, methodName: "execute_kw", parameters: params)
.responseXMLRPC(queue: DispatchQueue.global(qos: .background)) {
// process result
}
我是基于AlamofireXMLRPC的github source code,但之前没有用过,所以可能会有一些语法错误。但它应该为您指明正确的方向。尽管如此,我还是建议您不要阻塞线程(我重复一遍,但这确实非常重要)。
我需要来自网络服务的同步请求,所以我使用 sempahore:
class func syncProducts() {
print("syncProducts() 1")
let idsLocal = getProductsIds()
let semaphore = DispatchSemaphore(value: 0)
var idsCloud : [Int] = []
print("Getting cloud ids... 1")
OdooService.getProductsIds { (params: [Int]) in
print("SuccessBlock size ids: \(params.count) 1")
idsCloud = params
semaphore.signal()
}
semaphore.wait()
print("Depois do GetproductsIds: 1")
}
但在这个例子中,应用程序永远保持锁定状态!请求永无止境。这是我从网络服务器请求数据的功能,如果是的话,returns 到成功块。
static func getProductsIds(successBlock: @escaping (_ params: [Int]) -> Void) {
// check odoo auth
let dispatch = DispatchGroup()
if( OdooAuth.uid == 0 ) {
print("Odoo offline, tentando reconectar...")
dispatch.enter()
OdooAuth.reconnect(successBlock: { params in
print("Reconectado com sucesso...")
dispatch.leave()
}, failureBlock: { params in
print("Falha no ReAuth")
return
})
}
print("Start request from Odoo...")
let fieldsProducts = ["id"]
let options = [ "fields": fieldsProducts] as [String : Any]
var idsList : [Int] = []
let params = [OdooAuth.db, OdooAuth.uid, OdooAuth.password,"product.template","search_read",[],options] as [Any]
AlamofireXMLRPC.request(OdooAuth.host2, methodName: "execute_kw", parameters: params).responseXMLRPC {
(response: DataResponse<XMLRPCNode>) -> Void in
switch response.result {
case .success( _):
print("Success to get Ids")
let str = String(data: response.data!, encoding: String.Encoding.utf8) as String!
let options = AEXMLOptions()
let xmlDoc = try? AEXMLDocument(xml: (str?.data(using: .utf8))!,options: options)
//print(xmlDoc!.xml)
for child in (xmlDoc?.root["params"]["param"]["value"]["array"]["data"].children)! {
for childValue in child["struct"].children {
let id = childValue["value"]["int"].value!
idsList.append(Int(id)!)
//print("Id: \(id)")
}
}
successBlock(idsList)
break
case .failure(let error):
print("Error to get Ids: \(error.localizedDescription)")
break
} // fim switch
} // fim request
} // fim getProductsIds
我不知道信号量是否是执行此操作的最佳方式,但我需要同步请求!我试过像在 reauth 中那样使用 DispatchGroup(),但也不起作用。
我认为死锁是在主线程上调用 getProductsIds
回调的结果,主线程被信号量阻塞。据我所知,默认情况下 Alamofire 在主线程上调度回调,我希望 AlamofireXMLRPC 就是这种情况,因为它是 Alamofire 的包装器。
我强烈建议在异步操作期间不要阻塞主线程。
但是,如果出于任何非常好的原因您不能这样做,您将需要确保回调不会在主调度队列中调度(因为主调度队列被阻塞等待信号) . Alamofire 本身有一个 response
重载,允许指定 运行 回调的 DispatchQueue
对象。似乎 AlamofireXMLRPC 也有一个,所以我会尝试利用它并更改
AlamofireXMLRPC.request(OdooAuth.host2, methodName: "execute_kw", parameters: params)
.responseXMLRPC {
// process result
}
至:
AlamofireXMLRPC.request(OdooAuth.host2, methodName: "execute_kw", parameters: params)
.responseXMLRPC(queue: DispatchQueue.global(qos: .background)) {
// process result
}
我是基于AlamofireXMLRPC的github source code,但之前没有用过,所以可能会有一些语法错误。但它应该为您指明正确的方向。尽管如此,我还是建议您不要阻塞线程(我重复一遍,但这确实非常重要)。