У меня довольно сложная настройка табличного представления, и я решил использовать блок-структуру для создания и выбора ячеек, чтобы упростить будущую разработку и изменения.
Структура, которую я использую, выглядит так:
var dataSource: [(
cells:[ (type: DetailSection, createCell: ((indexPath: NSIndexPath) -> UITableViewCell), selectCell: ((indexPath: NSIndexPath) -> ())?, value: Value?)],
sectionHeader: (Int -> UITableViewHeaderFooterView)?,
sectionFooter: (Int -> UITableViewHeaderFooterView)?
)] = []
Затем я могу настроить таблицу в функции настройки и сделать мои методы делегатов довольно простыми
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = dataSource[indexPath.section].cells[indexPath.row].createCell(indexPath:indexPath)
return cell
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataSource[section].cells.count
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return dataSource.count
}
Я сделал аналогичную настройку раньше в другом TVC
var otherVCDataSource: [[ (type: DetailSection, createCell: ((indexPath: NSIndexPath) -> UITableViewCell), selectCell: ((indexPath: NSIndexPath) -> ())?)]] = []
Это решение отлично поработало.
Однако текущий источник данных с секцией Head и Footer, однако, дает мне EXC_BAD_ACCESS каждый раз, когда я пытаюсь получить доступ к indexPath в одном из блоков createCell.
createCell: {
(indexPath) in
let cell:CompactExerciseCell = self.tableView.dequeueReusableCellWithIdentifier(self.compactExerciseCellName, forIndexPath:indexPath) as! CompactExerciseCell
cell.nameLabel.text = "\(indexPath.row)"
cell.layoutMargins = UIEdgeInsetsZero
return cell
}
Приложение всегда сбой на
self.tableView.dequeueReusableCellWithIdentifier(self.compactExerciseCellName, forIndexPath:indexPath)
Что мне здесь не хватает? Почему я не могу получить доступ к indexPath в новой структуре, когда он отлично работает в старой структуре? Чем отличается управление памятью между этим кортежем и массивом?
UPDATE:
Итак, у меня был крайний срок, и я, наконец, должен был отказаться и переработать структуру данных.
Первая попытка заключалась вместо отправки indexPath в качестве параметра отправить строку и раздел и перестроить indexPath внутри блока. Это работало на все, что находится внутри структуры данных, но если я нажал на другой контроллер вида на ячейку, я получил еще один чрезвычайно странный сбой (некоторая ошибка malloc, которая является странной, когда я использую ARC) при удалении ячеек в следующем VC.
Я тоже пытался копаться в этом крахе, но больше не было времени тратить на это, поэтому мне пришлось перейти к другому решению.
Вместо этого tuple-array [([],)] я сделал два массива; один для ячеек и один для верхних и нижних колонтитулов. Эта структура устранила проблему сбой indexPath, но у меня все еще была проблема в следующем VC, что не прекращал сбой при удалении ячеек.
Окончательным решением или обходным путем было обращение к создателю ячейки и селектору "безопасно" с этим расширением:
extension Array {
subscript (safe index: Int) -> Element? {
return indices ~= index ? self[index] : nil
}
}
в основном оператор return в функциях делегата tableView выглядит следующим образом:
return dataSource[safe:indexPath.section]?[safe:indexPath.row]?.createCell?(indexPath: indexPath)
вместо
return dataSource[indexPath.section][indexPath.row].createCell?(indexPath: indexPath)
Я не вижу, как это имеет значение для следующего VC, поскольку ячейка не должна даже существовать, если возникла проблема с выполнением нулевого значения или поиск не существующих индексов в структуре данных но это все еще решило проблему, с которой я столкнулся с деактивацией ячеек в следующем VC.
Я до сих пор не знаю, почему изменение структуры данных и безопасного расширения для получения значений из массива помогает, и если у кого-то есть идея, я был бы счастлив услышать это, но я не могу в это время больше экспериментировать с решением, Я предполагаю, что безопасный доступ к значениям каким-то образом перераспределил значения и не позволил им освободиться. Возможно, кортеж не дал компилятору понять, что значения должны храниться в памяти или, может быть, у меня просто есть призрак в моем коде где-нибудь. Надеюсь, когда-нибудь я смогу вернуться и разобраться в нем более подробно...