2015-10-29 151 views
1

我正在创建一个页面,用户从UITableView中的行业列表中选择他们所在的行业。这是配置文件创建过程的一部分。当用户选择一个行业时,它会被勾选(如果以前没有选择)&未勾选(如果先前已选择)。Swift:当UITableView滚动得太快时,应用程序崩溃

我有代码工作,它能够成功地构建。一切工作正常,但是当我滚动速度过快,并出现以下错误应用程序崩溃:

2015-10-29 10:16:40.576 Protégé Version 1.0[10867:473794] * Terminating app due to uncaught exception 'NSRangeException', reason: '* -[__NSArrayM objectAtIndex:]: index 11 beyond bounds [0 .. 10]'

紧随其后的是“第一掷调用栈”和所有文件的清单。奇怪的是,这似乎只发生在我滚动得太快的时候。通常也会突然发生。

下面是我的代码如下。已经在网上搜索与我得到的错误消息有关的任何内容,并且对于这种情况似乎没有任何帮助。似乎无法弄清楚什么是错的,真的很感谢任何帮助。我是新来的Swift,所以让我知道如果我的代码中有任何错误!感谢提前:)

var array = ["Industry 1", "Industry 2", "Industry 3", "Industry 4", "Industry 5"] 
var itemsSelected: [String] = [] 

override func viewDidLoad() { 
    super.viewDidLoad() 
} 

要确定有多少行是

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    return array.count 
} 

要定义每个单个电池单元的内容

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 

    let cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell") 
    cell.textLabel?.text = array[indexPath.row] 

    for var i = 0; i < selectedCells.count; i++ { 
      let indexPath = NSIndexPath(forRow: selectedCells[i], inSection: 0) 
      let checkedCell = tableView.cellForRowAtIndexPath(indexPath) 
      checkedCell?.accessoryType = UITableViewCellAccessoryType.Checkmark 
    } 

    return cell 
} 

要创建数组存储被选中的单元格

var selectedCells: [Int] = [] 

要选择行 - 勾选&未选中标记

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
    tableView.deselectRowAtIndexPath(indexPath, animated: true) 
    let cell = tableView.cellForRowAtIndexPath(indexPath) 

    // Checkmark & un-checkmark cell 
    if cell!.accessoryType == UITableViewCellAccessoryType.None { 
     cell!.accessoryType = UITableViewCellAccessoryType.Checkmark 
    } else { 
     cell!.accessoryType = UITableViewCellAccessoryType.None 
    } 

    // Add cell # to selectedCells array if it's a new selection. Remove if it's a deselection. 
    if selectedCells.contains(indexPath.row) { 
     selectedCells = selectedCells.filter {$0 != indexPath.row} 
    } else { 
     selectedCells.append(indexPath.row) 
    } 

    print(selectedCells) 
} 

传输所选字符串主简档创建视图控制器

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

    if segue.identifier == "selectionCompleted" { 

     // Get the new view controller using segue.destinationViewController 
     let destViewController: CreateProfileViewController = segue.destinationViewController as! CreateProfileViewController 

     // Pass the selected object to the new view controller. 
     destViewController.displayedSelection = array[0] 
    } 
} 

赛格瑞的增加速度回主要配置文件创建视图控制器

override func performSegueWithIdentifier(identifier: String, sender: AnyObject?) { 

    if identifier == "selectionCompleted" { 
     dispatch_async(dispatch_get_main_queue(), {() -> Void in 
      self.performSegueWithIdentifier("selectionCompleted", sender: nil) 
     }) 
    } 
} 
+0

可否请您打印indexPath.row中的cellForRowAtIndexPath并尝试滚动太快? 这可能是由于您的indexPath.row值大于数组中的值而引起的。 – Karlos

+0

我不认为访问存储字符串数组的问题的indexPath.row出现问题,因为单元格的数量似乎正确返回。 – MatthewLuiHK

回答

0

基于您提供的上下文。我猜这个问题可能是由于你的“内容定义方法”和选择的检查机制而发生的。

我的猜测:

在您的tableView(:UITableView的:NSIndexPath) - > UITableViewCell的功能, 它循环每当代表索要电池时间传递你selectedArray。

由于NSArray(数组)不是线程安全的,任何更改或快速访问selectedCell数组都可能导致各种状态。当“滚动这么快”会创建许多循环同时访问同一个数组时,我认为这里可能会发生一些冲突。

让我给个建议。您可以使用Set而不是数组。使用“包含”“插入”“删除”来控制状态,每个单元格只管理自己。

可能是这样的:

let cell = ... 
... 
if selectedSet.contains(indexPath.row){ 
    cell.accessoryType = UITableViewCellAccessoryType.Checkmark 
}else{ 
    cell.accessoryType = UITableViewCellAccessoryType.None 
} 
... 
return cell