【问题标题】:Caught NSInternalInconsistencyException request for rect at invalid indexPath在无效的 indexPath 处捕获 NSInternalInconsistencyException 对 rect 的请求
【发布时间】:2016-12-07 17:58:51
【问题描述】:

以下行使程序崩溃:

let cell = tableView.dequeueReusableCellWithIdentifier("ItemCell", forIndexPath: NSIndexPath(forRow: 0, inSection: 0)) as! ItemCell

控制台日志显示以下错误:

"caught "NSInternalInconsistencyException", "request for rect at invalid index path (<NSIndexPath: 0xc000000000000016> {length = 2, path = 0 - 0})"

这是我检查过的项目的要点列表:

  • 身份检查器中列出了正确的 Storyboard ID
  • 身份检查器中列出了正确的自定义类
  • 属性检查器在表格视图单元格标识符字段中有“ItemCell”

这里是完整的代码:

import XCTest
@testable import ToDo

class ItemCellTests: XCTestCase {

    override func setUp() {
        super.setUp()
        // Put setup code here. This method is called before the invocation of each test method in the class.
    }

    override func tearDown() {
        // Put teardown code here. This method is called after the invocation of each test method in the class.
        super.tearDown()
    }

    func testSUT_HasNameLabel(){

        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let controller = storyboard.instantiateViewControllerWithIdentifier("ItemListViewController") as! ItemListViewController

        _=controller.view

        let tableView = controller.tableView
        tableView.dataSource = FakeDataSource()

        let cell = tableView.dequeueReusableCellWithIdentifier("ItemCell", forIndexPath: NSIndexPath(forRow: 0, inSection: 0)) as! ItemCell


        XCTAssertNotNil(cell.titleLabel)
    }
}


extension ItemCellTests{
    class FakeDataSource: NSObject, UITableViewDataSource {
        func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 1
        }

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

这里是 ItemCell.swift 代码:

import UIKit

class ItemCell: UITableViewCell {

    @IBOutlet weak var titleLabel: UILabel!


    func configCellWithItem(item: ToDoItem){

    }
}

与情节提要相关的所有属性都已连接。什么被忽视了?

【问题讨论】:

    标签: ios swift xcode xctest


    【解决方案1】:

    看起来这段代码来自我的书。这是书中已知的错误。将测试方法改为如下:

    func testSUT_HasNameLabel(){
    
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let controller = storyboard.instantiateViewControllerWithIdentifier("ItemListViewController") as! ItemListViewController
    
        _=controller.view
    
        let tableView = controller.tableView
        let dataProvider = FakeDataSource()
        tableView.dataSource = dataProvider
    
        let cell = tableView.dequeueReusableCellWithIdentifier("ItemCell", forIndexPath: NSIndexPath(forRow: 0, inSection: 0)) as! ItemCell
    
        XCTAssertNotNil(cell.titleLabel)
    }
    

    然后,当您稍后重构该代码以将设置放入setUp 方法时,将属性let dataProvider = FakeDataSource() 添加到测试用例并将其设置为@ 中的表视图(tableView.dataSource = dataProvider)的数据源987654325@.

    【讨论】:

    • 很高兴得到您的回答,但这样做有什么意义呢?
    • 书中的版本不起作用的原因是,tableViewdataSource 是一个弱引用。当您使用新实例设置它时,它会立即被释放。因此,您需要该对象的局部变量。我在写这本书时没有看到这一点,因为我在 iPhone 4s 模拟器上测试了代码并且没有崩溃。我不知道为什么。
    • @dasdom 原因是有道理的,但错误消息没有。你是如何找到问题的根源的?有什么让你明白的证据吗?
    • @Jean-DenisMuys 我添加了断点并使用调试器运行它。
    • 为了重构,我在类中添加了这个: var dataProvider: UITableViewDataSource!这样,测试用例中就没有重复的代码。
    【解决方案2】:

    到目前为止,我发现的一个解决方案是更改最初的问题子函数:

    let cell = tableView.dequeueReusableCellWithIdentifier("ItemCell", forIndexPath: NSIndexPath(forRow: 0, inSection: 0)) as! ItemCell
    

    通过更改为以下内容以通过测试:

    let cell = tableView.dequeueReusableCellWithIdentifier("ItemCell") as! ItemCell
    

    【讨论】:

    • 我在读同一本书,但遇到了同样的问题。虽然这解决了问题,但有什么好处呢?
    • 我是这本书的作者。请看我的回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-14
    • 2017-10-30
    • 1970-01-01
    • 1970-01-01
    • 2020-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多