如何正确调用 GrandCentralDispatch

Sar*_*vic 0 xcode asynchronous grand-central-dispatch ios swift

我正在尝试从我的 API 加载自定义数据类型并将其显示在我的 iOS 应用程序登录页面上。

据我了解,我应该这样称呼:

override func viewDidLoad() {
  performSelector(inBackground: #selector(fetchJSON), with: nil)
  let myCustomDataType = //how so I get this back
  tableView.reloadData()
 //...
}
Run Code Online (Sandbox Code Playgroud)

显然 fetchJSON 的声明应该在另一个文件中,所以我不会用它不需要做的事情来填充我的控制器。但是,我需要此函数来返回 [MyCustomDataType] 列表并将其显示在我的登录页面上。

func fetchJSON() -> [MyCustomDataType] {
  //get api, fetch data, put it in my custom data type list
  return myCustomDataType
}
Run Code Online (Sandbox Code Playgroud)

我使用闭包吗?创建全局 [MyCystomDataType]。或者我如何实现这一目标?请注意异步任务,因为我显示的表格单元格有点像 facebook 或 instagram 新闻提要页面。

vad*_*ian 5

如果fetchJSON异步加载数据,则必须添加完成处理程序

func fetchJSON(completion: @escaping ([MyCustomDataType]) -> Void){
    API.fetch { fetchedData in
        completion(fetchedData)
    }
}
Run Code Online (Sandbox Code Playgroud)

然后调用fetchJSON后台线程并在主线程上重新加载表视图

override func viewDidLoad() {
   DispatchQueue.global().async {
      self.fetchJSON { data in 
          DispatchQueue.main.async {
              self.myCustomDataType = data
              self.tableView.reloadData()
          }
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

喜欢流行异步的API URLSession,并Alamofire在后台线程上执行他们的网络请求含蓄。如果您打算使用其中一个,您可以省略第一个async块。

performSelector是一个过时的objective-c-ish API。不要在 Swift 中使用它

  • 你的回答一如既往地好(已投票),但我想补充一下 Rob 的观点,即通常你不必使用 GCD 来异步执行网络调用,因为 URLSession 已经是异步的。 (3认同)