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

Posted

技术标签:

【中文标题】NSIndexPath?在 Swift 中没有成员名称“行”错误【英文标题】:NSIndexPath? does not have a member name 'row' error in Swift 【发布时间】:2014-06-04 14:36:23 【问题描述】:

我正在使用 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 文件中进行了扩展。 【参考方案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】:

您可以为此调用使用可选的链接语法(如果 indexPathnil,则将 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,所以我不确定你所说的任何内容与这种情况有什么关系。

以上是关于NSIndexPath?在 Swift 中没有成员名称“行”错误的主要内容,如果未能解决你的问题,请参考以下文章

Swift - NSInvalidArgumentException 和 NSIndexPath

类型'(String,AnyObject)'在swift中没有下标成员

问题:“PrincipalViewController”在 swift 中没有名为“revealViewController”的成员

类型“Any”没有下标成员/Swift 3 [重复]

类型'URL'没有成员'fileURL' - Swift 3

UIApplicationDelegate 在 Swift 应用程序中没有名为 managedObjectContext 的成员