我一直在试图理解这个过程,我已经读了很多书,只是没有点击而已,所以如果有人可以帮我分解一下,我将不胜感激。
我有一种方法可以从URL检索JSON,进行解析,然后通过完成处理程序返回数据。我可以发布代码,但是它们都可以正常工作,而且我(大部分)都可以理解。
在我的完成处理程序中,我可以在控制台中打印数据,因此我知道它已经存在,到目前为止一切都很好。
接下来的一点是让我绊倒的。虽然我可以在完成处理程序中使用数据,但无法从包含处理程序的视图控制器中访问数据。
我希望能够将tableData.count传递给numberOfRows并获得“使用未解析的标识符'tableData'”
如果任何人都可以列出我接下来需要做的事情,我将非常感谢。谢谢!
编辑:根据要求添加代码
这是我在ViewController类中定义的完成处理程序:
var tableData: [Patient] = []
var completionHandler: ([Patient]) -> Void = { (patients) in
print("Here are the \(patients)")
}
在viewDidLoad中:
let url = URL(string: "http://***.***.***.***/backend/returnA")
let returnA = URLRequest(url: url!)
retrieveJSON(with: returnA, completionHandler: completionHandler)
在Networking.swift文件中定义:
func retrieveJSON(with request: URLRequest, completionHandler: @escaping ([Patient]) -> Void) {
// set up the session
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
// make the request
let task = session.dataTask(with: request as URLRequest) {
// completion handler argument
(data, response, error) in
// completion handler
guard let data = data else {
print("Did not recieve data")
completionHandler([])
return
}
do {
let decoder = JSONDecoder()
let Patient = try decoder.decode(Array<Patient>.self, from: data)
// print(Patient)
completionHandler(Patient)
}
catch let err {
print("Err", err)
completionHandler([])
}
}
task.resume()
}
我也定义了一个名为Patient的结构,但是由于它很长,并且仅是一个与接收到的JSON匹配的简单结构,所以我不会发布。
答案 0 :(得分:1)
首先,在使用闭包时,应考虑使用强引用周期。
let completionHandler: ([Patient]) -> Void = { [weak self] patients in
guard let strongSelf = self else { return }
strongSelf.tableData = patients // update tableData that must be used with UITableViewDataSource functions.
strongSelf.tableView.reloadData() // notify tableView for updated data.
}
答案 1 :(得分:0)
您没有在闭包中填充数组(tableData):
var completionHandler: ([Patient]) -> Void = {[weak self] (patients) in
print("Here are the \(patients)")
self?.tableData = patients
}
答案 2 :(得分:-1)
var tableData: [Patient] = []
var completionHandler: ([Patient]) -> Void = { (patients) in
self.tableData = patients
self.tableView.reloadData()
//make sure your tableview datasource has tableData property used
}