gpt4 book ai didi

ios - Swift:异步数据任务永远不会终止

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

我有一个函数可以抓取网站中嵌入的 JSON 文件并返回一个字符串数组。因为它返回的数据对我的 View Controller 来说是必不可少的,所以我需要这个函数在 View 加载之前运行。它在 View Controller 的初始化中被调用。

func scrapeBuses() -> [String] {
let config = URLSessionConfiguration.default
//config.waitsForConnectivity = true
let defaultSession = URLSession(configuration: config)
let url = URL(string: link to a JSON file)
let request = NSMutableURLRequest(url: url!)
request.cachePolicy = .reloadIgnoringLocalCacheData
var loops = [String]()
let group = DispatchGroup()
group.enter()
DispatchQueue.main.async {
let task = defaultSession.dataTask(with: request as URLRequest) { data, response, error in
do {
print("Getting information from website")
if let error = error {
print(error.localizedDescription)
} else if let data = data, let response = response as? HTTPURLResponse, response.statusCode == 200 {
print("in async")
loops.append("test2")
}
}
catch { print(error)}
}
}
task.resume()
print("about to return")
//return loops
}
group.wait()
return loops
}

因为它是异步的,所以我添加了 DispatchGroupwait() 语句,这样我的主线程会一直等到这个基本数据被抓取,然后再继续剩下的的线程。然而,我注意到当这个 View Controller 的 segue 发生时(即,当 View Controller 被初始化时)没有其他打印并且模拟停止。很明显这意味着主线程正在等待 scrape() 完成,但为什么它会无限运行?当我在网络浏览器和 Rested 中访问该网站时,我可以看到它正确地托管了 JSON。

编辑:

我使用完成处理程序而不是 DispatchQueue.wait() 尝试了同一函数的另一个版本。下面是代码:

func scrapeBuses(completion: @escaping ([String]) -> Void) {
let config = URLSessionConfiguration.default
let defaultSession = URLSession(configuration: config)
let url = URL(string: "https://www.cmunc.net/assets/appData.json")
let request = NSMutableURLRequest(url: url!)
request.cachePolicy = .reloadIgnoringLocalCacheData
var loops = [String]()

let task = defaultSession.dataTask(with: request as URLRequest) { data, response, error in
print("Getting information from website")
if let error = error {
print(error.localizedDescription)
} else if let data = data, let response = response as? HTTPURLResponse, response.statusCode == 200 {
print("in async")
loops.append("test2")
}
completion(loops)
}
task.resume()
}

下面是 View Controller 的 init 调用的函数:

func refresh() {
var newArray = [String]()
scrapeBuses { loops in
newArray = loops
print("calling scrapeBuses closure")
}
print(newArray)
}

使用完成处理程序,代码可以正确执行。 scrapeBuses 中的打印语句和关闭打印中的打印语句。非常感谢所有提供见解的人。

最佳答案

您应该向您的scrapeBuses 函数添加一个完成处理程序。

func scrapeBuses(completion: ([String]?, Error?) -> Void) {
// etc (remove all mentions of groups)

let task = defaultSession.dataTask(with: request as URLRequest) { data, response, error in
do {
print("Getting information from website")
if let error = error {
DispatchQueue.main.async { // Call back on the main queue
completion(nil, error)
}
} else if let data = data, let response = response as? HTTPURLResponse, response.statusCode == 200 {
print("in async")
loops.append("test2")
}
DispatchQueue.main.async {
completion(loops, nil)
}
}
catch {
DispatchQueue.main.async {
completion(nil, error)
}
}
}
task.resume()
}

然后……

func viewDidLoad() {
super.viewDidLoad()

scrapeBuses { loops, error in
if let error = error {
print(error)
return
}
// Do something with loops
}
}

关于ios - Swift:异步数据任务永远不会终止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52155235/

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