我研究了这个,似乎没有任何工作。 试图建立一个食谱应用程序和菜肴的形象&菜肴的名称(开胃菜)没有按顺序下载。我怎么能这样做?
代码:
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
答案 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非常乐于助人:)