gpt4 book ai didi

json - 如何将 DispatchSemaphore 与 Alamofire 和 SwiftyJSON 一起使用?

转载 作者:搜寻专家 更新时间:2023-11-01 06:33:42 24 4
gpt4 key购买 nike

我试图在方法外使用一些 json 响应,但在执行方法时它返回空数组,但在 block 内按预期工作,我的方法是否有任何方式返回预期值,这是我的示例代码:

func getCarouselContent(url: String) -> [String] {
var ids: [String] = []
let headers = ["api_key": "My_API_KEY"]

let semaphore = DispatchSemaphore(value: 0)
Alamofire.request(url, headers: headers).validate().responseJSON {
(response) in
semaphore.signal()
switch response.result {
case .success(let value):
let json = JSON(value)
let data = json["data"]["relationships"]["slides"]["data"]
for child in data.array! {
let id = child["id"].string!
print(id) // this prints all the id
ids.append(id)
}
case .failure(let error):
print(error)
}
}
semaphore.wait()
return ids
}

我正在使用 alamofire 和 swiftyjson 来解析 json。仅供引用,我对此并不陌生,并尝试了类似问题的回答中的解决方案,但没有奏效,非常感谢任何建议,谢谢。

最佳答案

解决您的原始问题然后提供更好的解决方案:

信号量。您可能过早发出信号。当从函数/闭包返回时,用于安全地向 DispatchSemaphore 发出信号的稳健习惯用法是使用 defer 语句。例如:

Alamofire.request(url, headers: headers).validate().responseJSON {    
(response) in {
defer {
semaphore.signal() // Executed before leaving current scope.
}
...
}

这确保您总是独立于退出点触发signal(),避免死锁。

话虽如此,这可能远非最佳解决方案...

完成处理程序。您将 getCarouselContent 方法设计为阻止调用代码,直到完成网络请求,这可能需要(非常!)很长时间。 如果您计划从您的应用主线程调用此方法,这肯定会导致非常糟糕的用户体验。让我们看看是什么 Apple says about this :

Be sure to limit the type of work you do on the main thread of your app. The main thread is where your app handles touch events and other user input. To ensure that your app is always responsive to the user, you should never use the main thread to perform long-running or potentially unbounded tasks, such as tasks that access the network. Instead, you should always move those tasks onto background threads.

解决此问题的常见模式是将完成 block 传递给您的getCarouselContent 方法。当 JSON 响应最终到达时,该 block 将传递结果。例如:

func getCarouselContent(url: String, completion: @escaping ([String]) -> Void) {
let headers = ["api_key": "My_API_KEY"]
Alamofire.request(url, headers: headers).validate().responseJSON {
(response) in
var ids = [String]()
switch response.result {
case .success(let value):
let json = JSON(value)
let data = json["data"]["relationships"]["slides"]["data"]
for child in data.array! {
ids.append(child["id"].string!)
}
case .failure(let error):
print(error)
}
completion(ids)
}
}

并这样调用它:

getCarouselContent(url: someUrl) {
(ids) in
print("IDs received: \(ids)")
}

关于json - 如何将 DispatchSemaphore 与 Alamofire 和 SwiftyJSON 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44231428/

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