我目前正在尝试将解析json得到的数据设置为RawDataCategory
文件中的ViewController
变量,该文件对json进行解码。
下面是我如何调用CategoryViewController
中的静态方法
class CategoryViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
var categoryProducts: [Datum]? // this is the variable i want with data i get
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
Datum.fetchProducts { (categoryProductsFromJSON) -> () in // here i call a static function.. i will paste the code below
self.categoryProducts = categoryProductsFromJSON //here i set value
print(self.categoryProducts?[0].name) // if i try to print the value in the scope i can access it. and it shows with no problem
}
print(categoryProducts?[0].name) //here is the problem. when i get out of the scope it return nil.
}
}
我可以访问作用域中的变量,但不知何故,当我试图在外部调用它时,它会打印nil
。
下面是我调用的静态函数(方法),以获取已解码的JSON:
static func fetchProducts(_ completionHandler: @escaping ([Datum]) -> ()) {
guard let url = URL(string: "http://localhost:8888/dayhandan/public/api/v1/category/1") else { return }
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url, completionHandler: { (data, response, error) -> Void in
if error != nil {
print("error")
return
}
do {
print("no error so far")
guard let data = data else { return }
let rawData = try JSONDecoder().decode(CategoryRawData.self, from: data)
DispatchQueue.main.async(execute: { () -> Void in
completionHandler(rawData.data ?? [])
})
} catch let err {
print(err)
}
})
task.resume()
}
我在解码JSON时没有得到任何错误。 实际上,我可以将它传递给我的ViewContoller
。 总体上没有错误。 当我在作用域之外调用categoryproducts
时,它就变成了零。
这是使用解码数据的好方法吗。 如果是的话,有人能帮我解决这个问题吗。 或者有人能指出一个好的方法来使用解码数据。 谢谢你抽出时间
这是因为您在后台线程中加载数据,当viewDidLoad运行时,它会立即打印CategoryProducts?[0].name
,而无需等待下面的代码。 您的加载数据异步
,因此程序不等待完成并切换到其他代码打印(categoryproducts?[0].name)
DispatchQueue.main.async(execute: { () -> Void in
completionHandler(rawData.data ?? [])
})
分类产品? 仍为空,因为上载尚未完成。
如果您用sync
更改,或将打印如下:
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
print(categoryProducts?[0].name)
}
你会看到区别。
10秒延迟是为了确保加载完成
您应该只尝试在完成处理程序中使用FetchProducts
的结果,因为完成处理程序将在将来的某个时间点执行。 完成处理程序之外的任何内容都将立即执行。