func handleGetAllPhotoURLs 从下面的行调用,我已确认该代码行仅在断点处执行一次。
_ = FlickrClient.getAllPhotoURLs(currentPin: self.currentPin, fetchCount: fetchCount, completion: self.handleGetAllPhotoURLs(pin:urls:error:))
根据我的 print 语句的输出,该函数运行两次,因为如果 urls.count 非零,它会打印两行输出。但是,如果 urls.count 为零,那么我只会得到一条打印语句,其中指出“urls.count ---> 0”
handleGetAllPhotoURLs ---> urls.count ---> 0//此行始终打印
handleGetAllPhotoURLs ---> urls.count ---> 21//仅当 urls 参数不为空时才打印此行
func handleGetAllPhotoURLs(pin: Pin, urls: [URL], error: Error?){
print("handleGetAllPhotoURLs ---> urls.count ---> \(urls.count)")
let backgroundContext: NSManagedObjectContext! = dataController.backGroundContext
if let error = error {
print("func mapView(_ mapView: MKMapView, didSelect... \n\(error)")
return
}
let pinId = pin.objectID
backgroundContext.perform {
let backgroundPin = backgroundContext.object(with: pinId) as! Pin
backgroundPin.urlCount = Int32(urls.count)
try? backgroundContext.save()
}
for (index, currentURL) in urls.enumerated() {
URLSession.shared.dataTask(with: currentURL, completionHandler: { (imageData, response, error) in
guard let imageData = imageData else {return}
connectPhotoAndPin(dataController: self.dataController, currentPin: pin , data: imageData, urlString: currentURL.absoluteString, index: index)
}).resume()
}
}
此外,我有一个 UILabel,仅在 urls.count 为零时才显示自己,并且我只想在 urls 为空时显示它。
现在,如果 urls 不为空,应用程序会很快闪烁空消息 UILabel。现在这对我来说是有意义的,因为 print 语句显示 urls 数组暂时为空。
有没有办法让我确定当 urls.count 非零时避免向用户闪烁空消息 UILabel?
编辑:根据请求添加了下面的代码。调用以下函数以在完成处理程序中获取 [URL]。然后完成处理程序被输入: func handleGetAllPhotoURLs(pin: Pin, urls: [URL], error: 错误?)
class func getAllPhotoURLs(currentPin: Pin, fetchCount count: Int, completion: @escaping (Pin, [URL], Error?)->Void)-> URLSessionTask?{
let latitude = currentPin.latitude
let longitude = currentPin.longitude
let pageNumber = currentPin.pageNumber
let url = Endpoints.photosSearch(latitude, longitude, count, pageNumber).url
var array_photo_URLs = [URL]()
var array_photoID_secret = [[String: String]]()
var array_URLString = [String]()
var array_URLString2 = [String]()
var count = 0
let task = URLSession.shared.dataTask(with: url) { data, response, error in
guard let dataObject = data, error == nil else {
DispatchQueue.main.async {
completion(currentPin, [], error)
}
return
}
do {
let temp = try JSONDecoder().decode(PhotosSearch.self, from: dataObject)
temp.photos.photo.forEach{
let tempDict = [$0.id : $0.secret]
array_photoID_secret.append(tempDict)
let photoURL = FlickrClient.Endpoints.getOnePicture($0.id, $0.secret)
let photoURLString = photoURL.toString
array_URLString.append(photoURLString)
getPhotoURL(photoID: $0.id, secret: $0.secret, completion: { (urlString, error) in
guard let urlString = urlString else {return}
array_URLString2.append(urlString)
array_photo_URLs.append(URL(string: urlString)!)
count = count + 1
if count == temp.photos.photo.count {
completion(currentPin, array_photo_URLs, nil)
}
})
}
completion(currentPin, [], nil)
return
} catch let conversionErr {
DispatchQueue.main.async {
completion(currentPin, [], conversionErr)
}
return
}
}
task.resume()
return task
}
最佳答案
在 do
block 中,您调用了 completion
两次。请查看更正,
do {
let temp = try JSONDecoder().decode(PhotosSearch.self, from: dataObject)
if temp.photos.photo.isEmpty == false {
temp.photos.photo.forEach{
let tempDict = [$0.id : $0.secret]
array_photoID_secret.append(tempDict)
let photoURL = FlickrClient.Endpoints.getOnePicture($0.id, $0.secret)
let photoURLString = photoURL.toString
array_URLString.append(photoURLString)
getPhotoURL(photoID: $0.id, secret: $0.secret, completion: { (urlString, error) in
guard let urlString = urlString else {return}
array_URLString2.append(urlString)
array_photo_URLs.append(URL(string: urlString)!)
count = count + 1
if count == temp.photos.photo.count {
completion(currentPin, array_photo_URLs, nil)
}
})
}
} else {
completion(currentPin, [], nil)
}
return
}
关于swift - 如果执行嵌套异步调用,则函数运行两次,否则运行一次。需要帮助预先确定这种情况何时发生,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55625101/