Можно ли присвоить массив свойству класса по ссылке, а не по копии?
Фон:
Я разработалTableViewDataSource
класс, который обеспечивает реализацию дляUITableViewDataSource
а такжеUITableViewDelegate
, Вы создаете экземплярTableViewSection
объекты, которые передаютсяTableViewDataSource
которые используются для настройки ячеек, заголовков разделов, выбора дескрипторов, вставки строк и т. д.
TableViewSection
Объект имеет свойство, называемоеdataSource: [AnyObject]?
, который, когда установлен, используется для вычисления количества строк в разделе и предоставления объекта для блока конфигурации ячейки:
// get the section, dequeue a cell for that section, retrieve the item from the dataSource
// ...
tableSection.cellConfigurationBlock?(cell: AnyObject, item: AnyObject?, indexPath: NSIndexPath)
return cell
Что я хотел бы сделать, это назначить ссылку на массив из моегоviewModel
к моемуtableSection.dataSource
имея мойviewModel
обновить массив, в свою очередь, обновив представление таблицы. В Swift вы не можете передать массив по ссылке. Обходной путь, кажется, заключается в использованииNSMutableArray
Но с этим приходит потеря безопасности типов и большая когнитивная нагрузка при переводе объектов назад и вперед из Swift в Foundation.
Рабочий пример:
let kCellIdentifier = "SomeCellIdentifier"
class MyViewController: UITableViewController {
// Property declarations
@IBOutlet var tableDataSource: TableViewDataSource!
var viewModel: MyViewControllerViewModel = MyViewControllerViewModel()
override func viewDidLoad() {
super.viewDidLoad()
self.setupTableView()
self.refresh()
}
func setupTableView() {
var tableSection = TableViewSection(cellIdentifier: kCellIdentifier)
tableSection.dataSource = self.viewModel.collection
// tableSection configuration
// ...
self.tableDataSource.addSection(tableSection)
}
func refresh() {
self.viewModel
.refresh()
.subscribeNext({ result in
self.tableView.reloadData()
}, error: { error in
self.logger.error(error.localizedDescription)
})
}
}
refresh()
метод наviewModel
попадает в мой сервис API, обновляет егоcollection
свойство на ответ, и предоставляет результат наnext
событиеRACSignal
(RACSignal
это класс, предоставляемыйРеактивный Какао и правда, кроме сути).
Я нашел один обходной путь, который включает переназначение источника данных каждый раз, когда производится одно обновление, или после пакетного обновления.
func refresh() {
self.viewModel
.refresh()
.subscribeNext({ result in
self.updateDataSource()
self.tableView.reloadData()
}, error: { error in
self.logger.error(error.localizedDescription)
})
}
func updateDataSource() {
self.tableDataSource.tableSectionForIndex(0)?.dataSource = viewModel.collection
}
Этот подход работает, но только временно, как обходной путь. КакTableViewDataSource
С ростом и усложнением этот метод становится все более сложным с императивным процедурным кодом, противоположным тому, что я намеревался достичь при написании класса.
Вопрос
Есть ли обходной путь, чтобы придерживаться родного SwiftArray
для достижения эквивалента прохождения фондаNSArray
или жеNSMutableArray
по ссылке?
Бонусный вопрос
Может ли кто-нибудь дать мне несколько советов по проектированию классов / структур для достижения желаемой цели в чистом Swift?