【发布时间】:2017-02-20 14:30:40
【问题描述】:
我正在尝试在 UITableViewController 上进行 MVVM 集成,但我不断收到:
fatal error: unexpectedly found nil while unwrapping an Optional value 上super.init(style: style, reuseIdentifier: reuseIdentifier)。
怎么会?我想这与它有关:
cell.menuItemViewModel = SideMenuViewModel(menuItem: item)
因为如果我删除此行没有错误?
在 sideMenuController 中设置数据源
func setupDatasource() {
let sections = [
SectionModel(model: "menu", items: menuItems)
]
dataSource.configureCell = { (ds, tv, ip, item) in
let cell: MenuCell = tv.dequeueReusableCell(withIdentifier: self.reuseIdentifier, for: ip) as! MenuCell
cell.menuItemViewModel = SideMenuViewModel(menuItem: item)
return cell
}
Observable.just(sections)
.bindTo(tableView.rx.items(dataSource: dataSource))
.addDisposableTo(disposeBag)
}
MenuItem 模型
struct MenuItem {
var title: String
var image: Asset
var imageSelected: Asset
var controller: UINavigationController
init(title: String, image: Asset, imageSelected: Asset, controller: UINavigationController) {
self.title = title
self.image = image
self.imageSelected = imageSelected
self.controller = controller
}
}
视图模型
struct SideMenuViewModel {
let title: String
let image: UIImage
let imageSelected: UIImage
init(menuItem: MenuItem) {
self.title = menuItem.title
self.image = UIImage(asset: menuItem.image)
self.imageSelected = UIImage(asset: menuItem.imageSelected)
}
}
菜单单元
class MenuCell: UITableViewCell {
var titleLabel: UILabel!
var iconImageView: UIImageView!
var menuItemViewModel: SideMenuViewModel! {
didSet {
//Set title
self.titleLabel.text = menuItemViewModel.title
//Set image
self.iconImageView.image = menuItemViewModel.image
}
}
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupUI()
setupConstraints()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
func setupUI() {
//Add titleLabel
self.titleLabel = UILabel()
self.addSubview(self.titleLabel)
//Add iconImageView
self.iconImageView = UIImageView()
self.addSubview(self.iconImageView)
//Customize titleLabel
self.titleLabel.font = FontFamily.Avenir.Regular.font(size: 26)
self.titleLabel.textColor = UIColor.white.withAlphaComponent(0.6)
//Customize iconImageView
self.iconImageView.contentMode = .scaleAspectFit
//Customize cell
self.selectionStyle = .none
self.backgroundColor = UIColor.clear
}
func setupConstraints() {
//titleLabel constraints
self.titleLabel.snp.makeConstraints({ make in
make.left.equalTo(self.iconImageView.snp.right).offset(-20)
make.centerY.equalTo(self)
make.height.equalTo(50)
make.width.equalTo(100)
})
//iconImageView constraints
self.iconImageView.snp.makeConstraints({ make in
make.left.equalTo(80)
make.centerY.equalTo(self)
make.height.equalTo(50)
make.width.equalTo(50)
make.right.equalTo(self.titleLabel.snp.left).offset(20)
})
}
}
【问题讨论】:
-
首先:调试并找出
nil是什么。如果它像您所说的那样在override init(style:, reuseIdentifier:)中,它必须是reuseIdentifier,因为它是唯一的可选afaics。但是你没有打开它,这很奇怪。这条线在我看来更可疑:let cell: MenuCell = tv.dequeueReusableCell(withIdentifier: self.reuseIdentifier, for: ip) as! MenuCell -
@shallowThought 好像
menuItemViewModel为零。 -
请用您的发现更新您的问题。确切的错误出现在哪里以及您已经发现了什么。也许打印调试结果来向我们展示
menuItemViewModel的确切位置是nil并解释为什么你认为此时它不应该是nil。