【问题标题】:NSIndexPath? does not have a member name 'row' error in SwiftNSIndexPath?在 Swift 中没有成员名称“行”错误
【发布时间】:2023-03-31 22:51:01
【问题描述】:

我正在使用 Swift 语言和方法创建一个 UITableViewController

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

我收到了这个错误

NSIndexPath?在 Swift 中没有成员名称“行”错误

我不明白为什么。

这是我的代码

import UIKit

class DPBPlainTableViewController: UITableViewController {

    var dataStore: NSArray = NSArray()

    override func viewDidLoad() {
        super.viewDidLoad()
        self.dataStore = ["one","two","three"]

        println(self.dataStore)
    }


    // #pragma mark - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView?) -> Int {

        // Return the number of sections.
        return 1
    }

    override func tableView(tableView: UITableView?, numberOfRowsInSection section: Int) -> Int {

        // Return the number of rows in the section.
        return self.dataStore.count
    }


    override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?) -> UITableViewCell? {
        let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")

        cell.textLabel.text = self.dataStore[indexPath.row]

        return cell
    }

}

那么,如何用数组dataStore元素设置cell.text呢?

【问题讨论】:

  • “我不明白为什么”因为NSIndexPath? 不是NSIndexPath。请记住,Optional 是一个枚举包装“真实”值。要访问该值,您需要打开它。
  • 行和节的 NSIndexPath 扩展在 UIKit 中的 UITableView.h 文件中进行了扩展。

标签: ios swift uitableview


【解决方案1】:

您可以使用if let... 解开可选的indexPath 参数:

if let row = indexPath?.row {
    cell.textLabel.text = self.dataStore[row]
}

或者如果您确定 indexPath 不是 nil,您可以使用 ! 强制展开:

cell.textLabel.text = self.dataStore[indexPath!.row]

请记住,nil 值上的indexPath! 将是一个运行时异常,因此最好像第一个示例一样将其解包。

【讨论】:

  • 或者,如果您确定indexPath 已定义(即不是nil),您可以使用! 语法将其内联展开,如下所示:dataStore[indexPath!.row]
  • 感谢 Nate Cook,我开始理解 ?在一个变量中。我会继续测试。谢谢大家
  • 不,不,不,不。行和节的 NSIndexPath 扩展在 UIKit 中的 UITableView.h 文件中进行了扩展。
  • @AlexZavatone 是的。但是,这里的问题是 OP 正在尝试访问 Optional<NSIndexPath> 的行和部分,而不是 NSIndexPath 没有这些属性。
【解决方案2】:

您可以为此调用使用可选的链接语法(如果 indexPath 是 nil,则将 cell.textLabel.text 设置为 nil):

cell.textLabel.text = indexPath? ? self.dataStore[indexPath!.row] : nil

或显式解包(如果 indexPath 为 nil,则会导致运行时错误):

cell.textLabel.text = self.dataStore[indexPath!.row]

或使用@NateCook 建议的更详细的if let 语法。

【讨论】:

  • 可选链接在您的第一个示例中有效吗?我认为 indexPath?.row 评估为 Int? 并且不能用作下标。
  • @NateCook:你是对的......你必须明确地测试。我已经编辑更正。看起来可选链下标不够聪明,无法通过可选链中的下标传播nil。我突然想到,您也许可以在实现subscript(index: Int?) -> String? 的dataStore 上进行扩展,但我将把它作为练习留给读者。
【解决方案3】:

使用 .item 代替 .row

cell.textLabel.text = self.dataStore[indexPath.item]

【讨论】:

    【解决方案4】:

    要访问NSIndexPath 的行和部分,您只需导入文件的标头,其中定义了基类NSIndexPath 的这些扩展名。

    如果你不这样做,你的类将像行和节一样在 NSIndexPath 的实例上不存在。

    NSIndexPath 的行和节扩展在 UITableView.h 内的 UIKit 框架内声明。

    要解决此问题,您只需将UITableView.h 导入您的班级即可。就是这样。

    在 Objective-C 的 UITableView.h 中定义了类的扩展。我确定 Swift 也有类似的部分。

    // This category provides convenience methods to make it easier to use an NSIndexPath to represent a section and row
    @interface NSIndexPath (UITableView)
    
    + (instancetype)indexPathForRow:(NSInteger)row inSection:(NSInteger)section;
    
    @property (nonatomic, readonly) NSInteger section;
    @property (nonatomic, readonly) NSInteger row;
    
    @end
    

    【讨论】:

    • 哈。谢谢日航。你和我都在同时添加代码块格式,但你打败了我。
    • 这不是问题。 UITableView.h 已经通过导入 UKit 导入。这个问题已经过时并且不再相关,因为 UITableViewDataSource 方法参数不再是可选的。
    • 如果您正在访问通过 UITableView.h 或 UICollectionView.h 扩展的 NSIndexPath 中的属性,并且您在视图控制器之外访问这些属性,那么您需要知道要导入什么文件以及为什么.我只是需要在课堂上这样做,所以我不知道你为什么告诉我这无关紧要。如果我需要的只是 NSIndexPath 中的一个类别,我不想将所有 UIKit 导入我的数据容器。这不合理吗?
    • 好吧,提问者正在从他的视图控制器内部访问这些属性,并且已经在导入 UIKit,所以我不确定你所说的任何内容与这种情况有什么关系。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多