indexPath.row 在 iPhone 6 模拟器上的计算不正确,但不是 4s/5/5s/6plus

Posted

技术标签:

【中文标题】indexPath.row 在 iPhone 6 模拟器上的计算不正确,但不是 4s/5/5s/6plus【英文标题】:indexPath.row incorrect calculation on iPhone 6 simulator but not 4s/5/5s/6plus 【发布时间】:2015-08-19 02:38:39 【问题描述】:

indexPath.row 在 iPhone 6 上的计算不正确,但在任何其他模拟器上都没有,如下所示。 ios 部署目标设置为 8.0。当您从(并且仅从)第 4 个选项卡单击分段控件中的第 2 个选项卡时,会发生此计算。

这是应用崩溃的地方:

func createCompletedCell(indexPath: NSIndexPath) -> CompletedCell 
    var cell = tableView.dequeueReusableCellWithIdentifier(profileCompletionId) as! CompletedCell
    println("indexPath.row: \(indexPath.row)")
    println("indexPath.row-2: \(indexPath.row-2)")
    var completion = switchState == 1 ? completionArr[indexPath.row-2] : favArr[indexPath.row-2] //crashes on this line

    cell.setCompletedCell(completion)
    return cell

调用自:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
    if indexPath.row == 0 
        var cell = tableView.dequeueReusableCellWithIdentifier("ProfileDetails", forIndexPath: indexPath) as! ProfileDetails
        cell.selectionStyle = UITableViewCellSelectionStyle.None //No background color if cell is clicked
        return cell
    
    else if indexPath.row == 1 
        var cell = tableView.dequeueReusableCellWithIdentifier("SegControl", forIndexPath: indexPath) as! ProfileSegControl
        cell.segControl.selectedSegmentIndex = switchState
        cell.segControl.addTarget(self, action: Selector("changeState:"), forControlEvents: UIControlEvents.ValueChanged)
        return cell
    
    else 
        if(switchState == 0 || switchState == 2)
            return createBountyCell(indexPath)
        
        else 
            return createCompletedCell(indexPath)
        
    

当我在 iPhone 6 模拟器上打印 indexPath.row 变量时,我点击第 4 个分段控制选项卡,然后点击第 2 个,我得到输出:

(4th tab calcs)    
indexPath.row: 2
indexPath.row-2: 0
indexPath.row: 3
indexPath.row-2: 1
(2nd tab calcs)
indexPath.row: 3
indexPath.row-2: 1

当我用 iPhone 4s/5/5s/6plus 做同样的事情时

(4th tab calcs)    
indexPath.row: 2
indexPath.row-2: 0
indexPath.row: 3
indexPath.row-2: 1
(2nd tab calcs)
indexPath.row: 2
indexPath.row-2: 0

问题是,当我单击第二个选项卡时,indexPath.row 应该设置为 2,但改为设置为 3。

【问题讨论】:

你看过你的故事板了吗? 是的,但看起来没什么异常。我到底应该看什么? @ILikeTau 表格视图。或者,您可以尝试将您的更改与 git 同步并重试吗? (记得在模拟器中重置内容和设置,这样一切都消失了)。 @ILikeTau 看了看,一切正常。我们确实注意到了,但是我们都使用了不同的版本,这就是问题所在。然而,我们仍然不确定为什么会发生这种情况。 好的,所以没有问题。在cellForRowAtIndexPath 中,未“计算”索引路径。就是这样。它是表格当时恰好需要的单元格的索引路径。你不应该对此做任何假设:你应该只提供进入它所在行的单元格。 【参考方案1】:

你的逻辑有问题。考虑一下您的代码大纲。首先你说:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
    if indexPath.row == 0  // ...
    
    else if indexPath.row == 1  // ...
    
    else 
        if(switchState == 0 || switchState == 2) // ...
        
        else 
            return createCompletedCell(indexPath)
        
    

好的。那么当您调用createCompletedCell 时,这是什么索引路径?你不知道!你忘了测试那个。相反,您测试的是完全不同的东西——关于switchState 的东西,我没有任何假设的基础。所以indexPath 行此时可以是除 0 或 1 之外的任何数字(因为如果它是其中之一,我们现在应该已经返回了)。

所以如果它是 2,你不应该感到惊讶,因为你的逻辑允许这种可能性。您的错误是稍后假设它不可能是 2,因为显然它可以是。

【讨论】:

我们的假设是 cellForRowAtIndexPath 在进程中是线性的,即从 0 开始到 X 个单元格结束。从你说的情况来看,我认为这是不正确的? 实际上放弃了这个问题,这里有一个关于为什么它不应该崩溃的例子:我们的数组中有 5 个项目。我们在 NumberOfRowsInSection 中让 tableview 知道我们有 5 个单元格要创建 + 2 个为我们的静态单元格,所以总共 7 个单元格。在 cellForRowAtIndexPath 中,我们检查静态单元格的行是 0 还是 1,否则我们想从 indexPath.row-2 处的数组中检索一个对象(减去 2 个静态单元格)。这给了我们结果,例如当 indexPath.row 为 5 时,我们正在从数组 [3] 中检索对象。在任何情况下 indexPath.row > 6 (array[4]) 都不会,因为我们之前指定了最多 7 个单元格。

以上是关于indexPath.row 在 iPhone 6 模拟器上的计算不正确,但不是 4s/5/5s/6plus的主要内容,如果未能解决你的问题,请参考以下文章

在 xcode 8 beta 6 的 UITableView 中使用 indexPath.row 将无法编译

UITableView 中的 indexPath 和 indexPath.section

如何“重置”下一个 indexPath.row 成为当前 indexPath.row?

indexPath.row 在 tableView didSelectRowAtIndexPath 中返回 null

如何在 UITableView 中获取选定的 indexPath.section 和 indexPath.row 值?

在 ViewDidLoad 中使用 objectAtIndex:indexPath.row [关闭]