【发布时间】:2019-11-26 15:24:55
【问题描述】:
我认为这个问题已经出现了很多次,但我无法理解所有 GCD 和完成处理的东西。非常感谢您提供一些指向有用文章的链接的快速修复。
我有一个从网络请求中获取和处理数据的函数:
func getTracklist(album id: String) -> String {
//create a GET request
let task = URLSession.shared.dataTask(with: request) { (data, response, error) -> Void in
guard let data = data else { return }
let decoder = JSONDecoder()
if let jsonTracks = try? decoder.decode(TrackRoot.self, from: data) {
tracks = jsonTracks.items!
}
//append the tracklist string
for track in tracks {
combinedTracks += "\(track.id)%2C"
}
}
task.resume()
return String(combinedTracks.dropLast(3))
}
返回的值在另一个函数中使用:
formattedAlbum.trackList = self.getTracklist(album: album.id!)
你可能已经猜到了,第一个函数没能及时获取数据,给tracklist分配了一个空字符串。
使用 Alexey 的回答:
for album in self.albums {
let formattedAlbum = AlbumFormatted(context: self.persistenceManager.context)
formattedAlbum.albumName = album.name
self.getTracklist(album: album.id!) { (data) in
formattedAlbum.trackList = data
}
self.formattedAlbums.append(formattedAlbum)
print(formattedAlbum)
}
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + .seconds(5)) {
print(self.formattedAlbums[1])
}
func getTracklist(album id: String, completion: @escaping (String?)->()) {
//URLSession stuff
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
guard let data = data else { return }
let decoder = JSONDecoder()
if let jsonTracks = try? decoder.decode(TrackRoot.self, from: data) {
tracks = jsonTracks.items!
for track in tracks {
combinedTracks += "\(track.id),"
}
completion(String(combinedTracks.dropLast()))
}
}
task.resume()
}
打印:
(entity: AlbumFormatted; id: 0x6000018fb400 <x-coredata:///AlbumFormatted/tFD0D9588-2820-451B-9A00-99175026ED043>; data: {
albumName = "Everyday Life";
trackList = "6Tb7Zfo4PcSiS4TqQ4NnTh,1e8D1BCD2afT56Km7UahpB,45PqOIkZ9PdCjsCJQYzx9G,1cXXhzPnbrXjNQYbLdUJdy,3pcPPhPAiurm2Ior11SHrz,7jib2tJjQ82kTIZZATMvAK,0ZlVUhjO8c0bOx1D2Btznf,0UvUivL70eDwhTWBd8S38I,6VzRvCbolqcUswaS";
})
【问题讨论】:
-
你怀疑这是一个骗子,但要知道要骗哪个,这个方法的调用者是主队列上的(即它是 UI 代码的一部分)吗?如果是,那么你不能这样做(你需要一种不同的方法)。如果不是,那么有一种技术。最简单的骗子搜索在这里:stackoverflow.com/search?q=%5Bswift%5D+async+return
-
@RobNapier,这都是用来填充模型的,所以不涉及 UI 的东西。感谢您的链接,我会继续搜索。
-
问题是
dataTask(with:completionHandler:)是一个异步函数,意思是该函数立即返回,但是一旦收到来自服务器的响应,完成处理程序将在稍后的时间点执行。最好理解异步函数以及为什么需要完成处理程序。在您的函数中,getTracklist需要一个完成处理程序作为参数。 -
澄清:1.
jsonTracks是否包含正确解码的json? 2.tracks打印出来了吗?这是否包含正确的参数? 3.combinedTracks是否包含想要的结果? -
@AlekseyPotapov,是的,最后一个代码 sn-p 中的 print(data) 语句正确打印出曲目,但没有为 formattedAlbum.trackList 分配任何内容。
标签: ios swift networking grand-central-dispatch