NSIndexPath? не имеет имени члена 'row' в Swift

Я создаю UITableViewController с языком Swift и в методе

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

Я получаю эту ошибку

NSIndexPath? не имеет имени члена 'row' в 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
    }

}

Затем, как установить cell.text с элементом массива dataStore?

Ответы

Ответ 1

Вы можете либо развернуть необязательный параметр indexPath с помощью if let...:

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

или если вы уверены, что indexPath не nil, вы можете принудительно развернуть с помощью !:

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

Просто имейте в виду, что indexPath! по значению nil будет исключением для выполнения, поэтому лучше развернуть его, как в первом примере.

Ответ 2

Вы можете использовать необязательный синтаксис цепочки для этого вызова (установка cell.textLabel.text в nil, если indexPath есть nil):

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

или явно разворачивать его (вызывая ошибку выполнения, если indexPath nil):

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

или используйте более подробный синтаксис if let, предложенный @NateCook.

Ответ 3

Используйте.item вместо.row

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

Ответ 4

Все, что вам нужно сделать для доступа к строке и разделу NSIndexPath, нужно импортировать заголовок файла, в котором определены эти расширения для базового класса NSIndexPath.

Если вы этого не сделаете, ваш класс будет действовать, как строка и раздел просто не существуют в экземпляре NSIndexPath.

Расширения строк и секций до NSIndexPath объявляются в рамках UIKit внутри UITableView.h.

Чтобы устранить эту проблему, все, что вам нужно сделать, это импортировать UITableView.h в ваш класс. Что это.

Вот где расширения класса определены в UITableView.h в Objective-C. Я уверен, что 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