如何按升序下载一行上的名称和图像

时间:2016-04-18 00:11:07

标签: swift2 ios9

我研究了这个,似乎没有任何工作。 试图建立一个食谱应用程序和菜肴的形象&菜肴的名称(开胃菜)没有按顺序下载。我怎么能这样做?

代码:

class Appetizers: UITableViewController {

    var valueToPass: String!
    var valuePassed: String!
    var appetizer = [String]()

    var images = [UIImage]()


    func refresh() {

        dispatch_async(dispatch_get_main_queue(), {

            self.tableView.reloadData()

        })

    }


    override func viewDidLoad() {
        super.viewDidLoad()

        // Parse - class - column
        let query = PFQuery(className: "Appetizers")
        query.orderByAscending("appetizer")
        query.findObjectsInBackgroundWithBlock { (objects, error) -> Void in

            if error == nil {

                if let objects = objects {

                    for object in objects {




                        let load = object.objectForKey("appetizer") as! String
                        self.appetizer.append(load)

                        let imageFile = object["imageFiles"] as! PFFile
                        imageFile.getDataInBackgroundWithBlock({ (imageData: NSData?, error: NSError?) -> Void in

                            if error != nil {

                                print(error)

                            } else {

                                if let data = imageData {

                                    self.images.append(UIImage(data: data)!)
                                    self.tableView.reloadData()

                                }

                            }
                        })

                        self.tableView.reloadData()

                    }

                }

            } else {

                print("Error: \(error!) \(error!.userInfo)")

            }
        }

        sleep(1)
        refresh()
    }


    override func viewWillAppear(animated: Bool) {

        self.tableView.reloadData()
    }


    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return appetizer.count
    }


    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)

        cell.textLabel?.text = appetizer[indexPath.row]

        // add image to table
        if images.count > indexPath.row {

            cell.imageView?.image = images[indexPath.row]

        }

        return cell
    }


    // when user taps on cell ...

    func getCellLabel () {

        let indexPath = tableView.indexPathForSelectedRow!
        let currentCell = tableView.cellForRowAtIndexPath(indexPath) as UITableViewCell!

        valueToPass = currentCell.textLabel!.text

    }


    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

        getCellLabel()
        self.performSegueWithIdentifier("0", sender: self)

    }


}

非常感谢任何帮助!

LizG

2 个答案:

答案 0 :(得分:0)

执行异步查询时,您无法保证其完成的顺序。因此,两个独立数组的概念,一个是字符串数组,另一个是图像数组,总是有问题的。

例如,您可以将images替换为由开胃菜名称索引的词典,因此它们完成的顺序并不重要。

var appetizer = [String]()
var images = [String: UIImage]()

因此,它可能看起来像:

override func viewDidLoad() {
    super.viewDidLoad()

    let query = PFQuery(className: "Appetizers")
    query.orderByAscending("appetizer")
    query.findObjectsInBackgroundWithBlock { objects, error in
        guard error == nil, let objects = objects else {
            print(error)
            return
        }

        for (index, object) in objects.enumerate() {
            let appetizerName = object.objectForKey("appetizer") as! String
            self.appetizer.append(appetizerName)

            let imageFile = object["imageFiles"] as! PFFile
            imageFile.getDataInBackgroundWithBlock { imageData, error in
                guard error == nil, let data = imageData else {
                    print(error)
                    return
                }

                // when the image comes in, asynchronously update only that one row

                self.images[appetizerName] = UIImage(data: data)
                self.tableView.reloadRowsAtIndexPaths([NSIndexPath(forRow: index, inSection: 0)], withRowAnimation: .Fade)
            }
        }

        // reload the table only once, after all of the `appetizer` entries are created (but likely before the images come in)

        self.tableView.reloadData()
    }
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)

    let name = appetizer[indexPath.row]
    cell.textLabel?.text = name
    cell.imageView?.image = images[name]

    return cell
}

或者您可以将这两个单独的属性替换为自定义对象数组(例如,Appetizer属性同时具有name属性和image属性的属性。

但无论如何,你要确定你没有处理两个独立的阵列。

顺便说一下,如果您有很多行,那么加载所有图像的过程可能会有问题。此代码正在使用" eager"加载图像(无论他们当前是否需要加载它们)。问题是图像是相对较大的资产(与字符串值相比),您可能遇到内存问题,网络带宽问题等。

一个人通常喜欢使用"懒惰"加载(例如,让cellForRowAtIndexPath仅在需要时请求图片。例如,假设您有200行,其中一行只能看到12行。您不应该这样做。请求200张图片,而只是请求12张图片。如果您从viewDidLoad中取出图片,而是cellForRowAtIndexPath一次请求一张图片,那么您就可以了。 ll具有更好的网络性能和更低的内存特性。

如果您要将图像保存在某些结构中,就像代码当前所做的那样,至少要确保在收到内存警告通知后清除这些图像(显然,优雅地处理根据需要以JIT方式请求它们。

答案 1 :(得分:0)

我发现我的表没有加载而没有加载()的问题... 我有自己的.tableView.reloadData()'在街区之外。 Rob非常乐于助人:)