gpt4 book ai didi

arrays - 索引 0 超出空数组的范围,有时有效,有时无效

转载 作者:行者123 更新时间:2023-11-30 13:58:32 24 4
gpt4 key购买 nike

MainTVC 通过从 parse.com 检索 PFObjects 在 tableView 中显示帖子的图片和标题,如果我点击 tableView Cell 之一,它将显示包含图片和文本的详细帖 subview 。 mainTVC 使用prepareForSegue 将数据传递给detailView。

大多数时候,它运行良好,但是当我尝试在 tableView 显示图片后立即点击它或者我滚动得非常快时,我会收到错误,特别是当我在网速较慢的情况下执行此操作时。

2015-10-22 14:36:52.501 bany[2595:874380] * Terminating app due to uncaught exception 'NSRangeException', reason: '* -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array’

2015-10-22 14:39:40.855 bany[2600:875293] * Terminating app due to uncaught exception 'NSRangeException', reason: '* -[__NSArrayM objectAtIndex:]: index 2 beyond bounds for empty array'

有时我得到的索引 2 超出了空数组的范围,有时为零。

我不认为我有一个空的indexPath。

我想,我在检索数据完成之前就点击了它。

这是我的 MainTVC 代码

import UIKit
import Parse

class MainTVC: UITableViewController {

@IBOutlet weak var categorySegment: UISegmentedControl!

var resultSearchController : UISearchController!



lazy var postsArray : NSMutableArray = NSMutableArray()
lazy var filterdArray : NSMutableArray = NSMutableArray()
var objectArray = [String]()
var parentObjectID = String()

var objectTwo : PFObject!
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(true)

//사이즈 조절

//tableView.estimatedRowHeight = tableView.rowHeight
//tableView.rowHeight = UITableViewAutomaticDimension


bringAllDatafromParse()
}


@IBAction func segmentTapped(sender: AnyObject) {




postsArray = []



switch categorySegment.selectedSegmentIndex {
case 0 :
bringAllDatafromParse()
case 1 :
bringCategoryDataFromParse(1)

case 2 :
bringCategoryDataFromParse(2)

case 3 :
bringCategoryDataFromParse(3)

default :
bringAllDatafromParse()



}
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 {

return postsArray.count


}





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





var postObjects = self.postsArray.objectAtIndex(indexPath.row) as! PFObject




cell.didRequestToShowComment = { (cell) in
let indexPath = tableView.indexPathForCell(cell)
let objectToSend = self.postsArray[indexPath!.row] as? PFObject
// Show your Comment view controller here, and set object to send here
self.objectTwo = objectToSend!
self.performSegueWithIdentifier("mainToComment", sender: self)


}
cell.soldLabel.hidden = true

if (postObjects.objectForKey("sold") as! Bool) == true {
cell.soldLabel.hidden = false

}

//제목

cell.titleLabel.text = postObjects.objectForKey("titleText") as! String

// 닉네임

if let nickNameExists = postObjects.objectForKey("nickName") as? String {
cell.nickNameLabel.text = nickNameExists
}else {
cell.nickNameLabel.text = postObjects.objectForKey("username") as? String
}



//시간
let dateFormatter:NSDateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MM /dd /yy"
cell.timeLabel.text = (dateFormatter.stringFromDate(postObjects.createdAt!))



// 가격

let price = (postObjects.objectForKey("priceText") as! String)
cell.priceLable.text = " $\(price)"



// 이미지
let mainImages = postObjects.objectForKey("front_image") as! PFFile


mainImages.getDataInBackgroundWithBlock { (imageData, error) -> Void in
let image = UIImage(data: imageData!)
cell.mainPhoto.image = image
}

// 프로필
if let profileImages = (postObjects.objectForKey("profile_picture") as? PFFile){
profileImages.getDataInBackgroundWithBlock { (imageData, error) -> Void in
let image = UIImage(data: imageData!)
cell.profilePhoto.image = image

}

}else{ cell.profilePhoto.image = UIImage(named: "AvatarPlaceholder")
}
circularImage(cell.profilePhoto)

return cell
}


// MARK: - Animate Table View Cell

// override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
// cell.alpha = 0
// UIView.animateWithDuration(0.5) { () -> Void in
// // cell.alpha = 1
// }
// }
//


func bringAllDatafromParse() {
//activityIndicatorOn()

postsArray = []
let query = PFQuery(className: "Posts")

query.orderByAscending("createdAt")
query.findObjectsInBackgroundWithBlock { (objects: [PFObject]?, error) -> Void in
if error == nil && objects != nil{

for object : PFObject in objects! {

self.postsArray.addObject(object)

}

let array : Array = self.postsArray.reverseObjectEnumerator().allObjects


self.postsArray = array as! NSMutableArray


}
self.tableView.reloadData()

}

}





func bringCategoryDataFromParse(category : Int) {



let query = PFQuery(className: "Posts")
query.whereKey("category", equalTo: category)
query.orderByAscending("createdAt")
query.findObjectsInBackgroundWithBlock { (objects: [PFObject]?, error) -> Void in
if error == nil && objects != nil{

for object : PFObject in objects! {

self.postsArray.addObject(object)

}

let array : Array = self.postsArray.reverseObjectEnumerator().allObjects


self.postsArray = array as! NSMutableArray
self.tableView.reloadData()

}


}

}




override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

if (segue.identifier == "mainToComment") {


let destViewController : CommentVC = segue.destinationViewController as! CommentVC

let selectedRowIndex = self.tableView.indexPathForSelectedRow

destViewController.object = objectTwo


}

if (segue.identifier == "mainToDetail") {


let selectedRowIndex = self.tableView.indexPathForSelectedRow
let destViewController : DetailVC = segue.destinationViewController as! DetailVC
destViewController.object = (postsArray[(selectedRowIndex?.row)!] as? PFObject)


}

}

func circularImage(image : UIImageView) {
image.layer.cornerRadius = image.frame.size.width / 2
image.clipsToBounds = true
image.layer.borderColor = UIColor.blackColor().CGColor
image.layer.borderWidth = 1
}

}

我的问题是

如果我的猜测是正确的,我应该如何处理从解析中检索数据的等待代码?

如果不是,这个错误的原因是什么?我该如何解决它?

最佳答案

您可能需要提供更多代码和详细信息,但我会想到两件事。

首先,根据函数的名称,您似乎正在将内容添加到另一个后台队列中的数组中,同时尝试通过 UI( TableView )在主队列上表示它们或与它们交互。我不确定 Parse 是如何工作的,但乍一看,我会确保您没有多个后台查询实例同时使用您的数组。

其次,我不清楚您如何处理单元格重用。在重新使用之前,您的单元格是否会尝试利用上次用于表示另一行的信息?也许您没有完全重置所有状态。

评论中问题的更新

查看 Parse(我从未使用过),我发现您没有正确使用它。 This example显示(在 Objective-C 中)应如何处理对 query.findObjectsInBackgroundWithBlock(...) 的调用。该示例似乎并未演示如何处理 UI 更新。

该 block 的内容正在后台运行。谷歌“cocoa UI 线程安全”并尽可能多地阅读。它也适用于更一般的线程安全问题。我认为每次您的 UI 创建表格单元格或与它们交互时,数组都会保存不同的内容(这会影响计数)。您还在后台对 postsArray 进行了大量替换,所有这些都会“绊倒”您的表格 View ,因为 UI 对象通常无法从除主队列之外的任何地方更新或操作/线。

您的情况似乎发生的是,查询正在后台更改数组,同时用户界面( TableView /单元格等)尝试更新。如果我告诉你“剥掉这五个土 bean 中的每一个”,然后当你还在剥第三个土 bean 的时候把它们全部倒掉,当你 Handlebars 伸进第四个土 bean 的(现在是空的垃圾箱)时,它不在那里,所以(愚蠢的土 bean -剥皮计算机程序,你是),你不知道该怎么做并说“但是没有第四个土 bean ”(“potatoes[3] is out ofbounds”),或者更糟的是,你捕获并剥离空气,或者你自己的手......你明白我的意思吗?

我的建议是查看该示例以及您在网络上可以找到的任何其他使用 findObjectsInBackgroundWithBlock(...) 的示例,以了解其他人如何处理 UI 更新。在我自己不深入研究的情况下,我认为 block 的内容应该处理向主线程上的可变数组添加内容并要求 TableView 更新。为此,也许一旦您确定查询已完成,在后台 block 中,“跳回”主队列以修改您的 postsArray 并更新表,如下所示:

// Inside the background block/closure, we've decided the query is complete,
// so we "hop to" the main thread to update our array and ask the UI to reflect it
dispatch_async(dispatch_get_main_queue()) { () -> Void in

self.postsArray.appendContentsOf(objects!)
self.tableView.reloadData()

}

这里的想法是,当执行 dispatch_async() 调用中的分派(dispatch) block /闭包时,UI 肯定会从上次扰乱它的任何内容中完成更新。这段小代码块被添加到主队列中,这意味着它(而且只有它)将在“运行循环之旅”期间执行。这可以确保对 posts 数组的任何更改和后续 UI 更新都会同时发生(正如它们应该发生的那样),并且一次仅发生一个。

您也应该将此逻辑/方法应用于其他查询,因为每个查询都可能导致相同的问题。我希望这会有所帮助。

关于arrays - 索引 0 超出空数组的范围,有时有效,有时无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33289282/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com