我试图在这个循环结束时重新加载tableView,但每当我尝试将self.tableView.reloadData()置于循环之外时,循环返回0.我想这是由于我&# 39;我在后台获取数据。在循环完成后,我该怎么做才能重新加载。
func loadData() {
var query = PFQuery(className: "Items")
query.includeKey("user")
query.getObjectInBackgroundWithId(itemId) {
(itemObject: PFObject!, error: NSError!) -> Void in
if (error == nil) {
var userObject = itemObject.objectForKey("user") as PFObject
let userImageFile = userObject.objectForKey("file") as PFFile
userImageFile.getDataInBackgroundWithBlock {
(imageData: NSData!, error: NSError!) -> Void in
if error == nil {
let image = UIImage(data:imageData)
self.detailDic?.setObject(itemObject.objectForKey("title"), forKey: "title")
self.detailDic?.setObject(itemObject.objectForKey("description"), forKey: "desc")
self.detailDic?.setObject(itemObject.objectForKey("location"), forKey: "point")
self.detailDic?.setObject(userObject.objectForKey("name"), forKey: "name")
self.detailDic?.setObject(userObject.objectForKey("gender"), forKey: "gender")
self.detailDic?.setObject(image, forKey: "image")
var relation = itemObject.relationForKey("file") as PFRelation
var imageQuery = relation.query() as PFQuery
imageQuery.findObjectsInBackgroundWithBlock { (imageObj: [AnyObject]!, error1: NSError!) -> Void in
if error1 == nil {
var imageDic:NSMutableArray = NSMutableArray()
let group = dispatch_group_create()
for obj in imageObj {
var imageObject = obj as PFObject
var thumbnail = imageObject.objectForKey("file") as PFFile
// Important: enter the group *before* starting the background task.
dispatch_group_enter(group)
thumbnail.getDataInBackgroundWithBlock {
(imageData: NSData!, error: NSError!) -> Void in
if error == nil {
let theImage = UIImage(data:imageData)
theImage.CGImage
self.imageArray!.addObject(theImage)
dispatch_group_leave(group)
}
}
}
dispatch_group_notify(group, dispatch_get_main_queue()) {
self.tableView?.reloadData()
}
}
}
}
}
}
}
}
答案 0 :(得分:2)
使用调度组。派遣小组基本上是一个柜台。您可以原子地递增和递减它,并且可以要求在它为零时收到通知。
每次添加后台任务时,“输入”该组(增加其计数器)。当后台任务完成时,“退出”该组(减少其计数器)。当计数器为零时使用dispatch_group_notify
运行一个块(意味着所有后台任务都已完成)。
let group = dispatch_group_create()
for obj in imageObj {
var imageObject = obj as PFObject
var thumbnail = imageObject.objectForKey("file") as PFFile
// Important: enter the group *before* starting the background task.
dispatch_group_enter(group)
thumbnail.getDataInBackgroundWithBlock {
(imageData: NSData!, error: NSError!) -> Void in
if error == nil {
let theImage = UIImage(data:imageData)
self.imageArray!.addObject(theImage)
dispatch_group_leave(group)
}
}
}
dispatch_group_notify(group, dispatch_get_main_queue()) {
self.tableView?.reloadData()
}
请注意,如果imageObj
中没有元素,或者所有后台任务在dispatch_group_notify
运行之前完成,dispatch_group_notify
将立即运行该块(这就是你想要的)。
此外,UIImage
在创建图像数据时不必解码图像数据。它可以懒散地这样做。您可能希望强制它解码后台线程上的图像数据。你可以通过询问CGImage
:
if error == nil {
let theImage = UIImage(data:imageData)
theImage.CGImage // force decoding immediately
self.imageArray!.addObject(theImage)
dispatch_group_leave(group)
}
答案 1 :(得分:0)
你也可以这样做:
for (index,obj) in enumerate(imageObj) {
.......
// reload after last loop
if(index == imageObj.count) {
self.tableView?.reloadData()
}
}