【发布时间】:2014-08-27 17:09:23
【问题描述】:
背景:
我设计了一个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)
})
}
}
viewModel 上的 refresh() 方法访问我的 API 服务,在响应时更新它的 collection 属性,并在 RACSignal 的 next 事件上提供结果(RACSignal 是一个提供的类Reactive Cocoa 真的,除此之外)。
我找到了一种解决方法,它涉及在每次进行单次更新或批量更新后重新分配数据源。
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 的增长和变得越来越复杂,这种方法变得越来越复杂,带有命令式程序代码,这与我在编写类时所要实现的目标相反。
问题
是否有任何解决方法可以坚持使用原生 Swift Array 来实现相当于通过引用传递 Foundation NSArray 或 NSMutableArray?
奖金问题
有人可以为我提供一些类/结构设计技巧以在纯 Swift 中实现预期目标吗?
【问题讨论】:
-
我添加了一个工作示例和更多细节。除非我遗漏了什么,否则我不相信
inout参数是我的解决方案。 -
嗯...这个标题可能会产生误导,你说在 Swift 中,你不能通过引用传递数组,如果提到传递给函数,就是不正确,因为它可以使用
inout完成。如果您的意思不同,最好至少更新一下标题。 -
同意。欣赏“口头”表达担忧,而不仅仅是投反对票。
-
新标题更有意义,现在很清楚你想要达到的目标:)
标签: swift class-design foundation