【问题标题】:Swift Dispatch Groups with Parse queries带有 Parse 查询的 Swift 调度组
【发布时间】:2015-12-14 19:26:31
【问题描述】:

我有 4 个包含 Parse query.findObjectsInBackgroundWithBlock 的函数。这些被调用来获取数据,然后填充表格视图。使用调度组。

这是我的解析查询的两个示例

func getEventImages() {
    print("getEventImages enter")
    dispatch_group_enter(self.group)

    let query = PFQuery(className: "events")
    query.orderByAscending("eventDate")
    query.findObjectsInBackgroundWithBlock { (objects:[AnyObject]!, error: NSError!) -> Void in
        // Initialize your array to contain all nil objects as
        // placeholders for your images
        if error == nil {
            self.eventMainImageArray = [UIImage?](count: objects.count, repeatedValue: nil)
            for i in 0...objects.count - 1 {

                let object: AnyObject = objects[i]
                let mainImage = object["mainImage"] as! PFFile
                //dispatch_group_enter(self.group)
                mainImage.getDataInBackgroundWithBlock({
                    (imageData: NSData!, error: NSError!) -> Void in
                    if (error == nil) {
                            let mainImage = UIImage(data:imageData)
                            self.eventMainImageArray[i] = mainImage
                            print("getEventImages appended")   
                    }
                    else {
                        print("error!!")
                    }
                })
            }
        }
        print("getEventImages leave")
        dispatch_group_leave(self.group)
    }
} 

func getEventInfo() {
    print("eventInfo enter")
    dispatch_group_enter(group)

let query = PFQuery(className: "events")
    query.orderByAscending("eventDate")
    query.findObjectsInBackgroundWithBlock { (objects:[AnyObject]!,error:   NSError!) -> Void in
        self.eventNameArray = [String?](count: objects.count, repeatedValue: nil)
        self.eventInfoArray = [String?](count: objects.count, repeatedValue: nil)
        self.eventDateArray = [NSDate?](count: objects.count, repeatedValue: nil)
        self.eventTicketsArray = [String?](count: objects.count, repeatedValue: nil)

        if error == nil {
            for i in 0...objects.count - 1 {
                let object: AnyObject = objects[i]
                let eventName = object["eventName"] as! String
                let eventInfo = object["eventInfo"] as! String
                let eventDate = object["eventDate"] as! NSDate
                let eventTicket = object["Tickets"] as! String

                self.eventNameArray[i] = eventName
                self.eventInfoArray[i] = eventInfo
                self.eventDateArray[i] = eventDate
                self.eventTicketsArray[i] = eventTicket
                print("event info appended")
            }
        }
        print("event info leave")
        dispatch_group_leave(self.group)
    }
}

还有我的 dispatch_group_nofity

 dispatch_group_notify(group, dispatch_get_main_queue()) { () -> Void in
        print("Finished reloadDataFromServer()")
        self.tableView.reloadData()
        self.refreshControl?.finishingLoading()
    }
}

问题在于,如果在调用 dispatch_group_leave(self.group) 之前足够快地检索到数据,则会导致过早重新加载 tableview 数据。我需要得到这个,以便在追加完成时调用 dispatch_group_leave。

【问题讨论】:

  • 为什么要解压 PFObject 并将属性存储在多个数组中?为什么不简单地将 PFObjects 本身存储在一个数组中,然后在创建表行时访问对象属性?存储事件数组还可以避免必须对事件发出两次相同的查询,然后您就不需要调度组。它还将使用更少的时间、数据和更少的 Parse 事务
  • 查看示例时,大多数人都是这样做的。此外,我猜测将来当我需要更新和更改某些对象时,为单个对象执行此操作会更容易,而不必再次抓取和更新整个 pfobject。你怎么看?
  • 你能给我举个例子来说明你的意思吗?我明白你在说什么,但我不太确定在创建行以及编辑和更新某些对象时如何使用它
  • 不,只保留PFObject,然后如果要更新它,只需更新属性并在其上调用save 方法之一。无需再次获取它。

标签: ios swift parse-platform grand-central-dispatch dispatch


【解决方案1】:

不需要两种方法来检索数据,不需要将数据解包到多个数组中,也不需要使用调度组。

您只需要一个简单的方法来检索您的事件数据

var events:[PFObject]=[PFObject]()

func getEventInfo() {
    let query = PFQuery(className: "events")
    query.orderByAscending("eventDate")
    query.findObjectsInBackgroundWithBlock { (objects:[AnyObject]!,error:   NSError!) -> Void in
        if error==nil {
            self.events=objects as! [PFObject]
            self.tableView.reloadData()           
        } else {
            print("Something went wrong! - \(error)"
        }
        self.refreshControl?.finishingLoading()
    }
}

那么,你还没有显示你的cellForRowAtIndexPath,但你会有类似的东西

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    var cell = self.tableView.dequeueReusableCellWithIdentifier("cell") as! MyTableViewCell
    let event=self.events[indexPath.row]

    cell.eventName.text=event["eventName"] as? String
    cell.eventInfo.text=event["eventInfo"] as? String
    if let mainImageFile=event["mainImage"] as? PFFile {
        mainImageFile.getDataInBackgroundWithBlock({
            (imageData: NSData!, error: NSError!) -> Void in
            if (error == nil) {
                let mainImage = UIImage(data:imageData)
                cell.mainImage= mainImage
            }
            else {
                print("error!!")
            }
    }
    return cell;
}

您可以使用PFImageViewSDWebImage 之类的框架来处理图像缓存并在加载图像时将占位符图像放置到位。

如果你想更新一个事件就这么简单

 var event=self.events[someindex];
 event["eventName"]=newValue
 event.saveInBackground()

【讨论】:

  • 你可能想在主线程上调用 UI 的东西:我一直不清楚 Parse 完成处理程序是否在它上面。
  • 解析完成处理程序在主队列上调度,现在该框架是开源的,如果您愿意,您可以自己验证这一点。
  • 刚刚试了一下,真的清理了我的代码!谢谢
  • 在单元格的 mainImageFile.getDataInBackground 之后。然后我将如何捕获所有这些以便能够将它们移动到 func didSelectRowAtIndexPath 中的详细视图中?我正在使用我之前创建的数组执行此操作,但现在不太确定如何进行。此外,我还有第二张图像,我必须为详细视图准备好 DataInBackground。在 didSelectRow 中调用它是不正确的吗?谢谢保罗!!
  • 您可以使用像 SDWebImage 这样的框架,它会为您处理缓存,然后在您的详细视图中再次获取图像。第二次它将来自缓存并快速提供。我会在viewDidLoad 中获取第二张图片,或者在您的详细视图控制器中获取属性观察者。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-26
相关资源
最近更新 更多