我面临着“无法分配给'布尔'类型的不可变表达式”的问题。请看下面的代码。我在viewForHeaderInSection
中遇到错误。实际上,我应该在哪里进行修改以使其正常工作?。
struct VenueDetail {
var isVeg: Bool
}
struct VenueDetailDTOMapper {
static func map(_ dto: DetailDataDTO) -> VenueDetail {
return VenueDetail(isVeg: dto.isVeg)
}
}
在API管理器中,我从api中获取了数据,并按照以下说明使用上述结构
let venueDetail = VenueDetailDTOMapper.map(getDetail)
ViewModel:
enum VenueDetailVMTypes {
case veueInfoInfo
}
protocol VenueDetailVMItems {
var type: VenueDetailVMTypes { get }
}
struct VenueInfoViewModel: VenueDetailVMItems {
var type: VenueDetailVMTypes {
return .veueInfoInfo
}
var headerSection: VenueDetail
}
func cretaDataSource() {
if let getVenueDetails = self.venueDetails {
let vmType = VenueInfoViewModel(headerSection: getVenueDetails)
arrayDataSource.append(vmType)
}
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView()
let venueDetailVMItems = viewModel.arrayDataSource[section]
switch venueDetailVMItems.type {
case .veueInfoInfo:
let headerCell = tableView.dequeueReusableCell(withIdentifier: kCellIdentifierVenueHeader) as! VenueHeaderTVCell
headerCell.updateCellData(detail: (venueDetailVMItems as! VenueInfoViewModel).headerSection)
headerCell.foodTypeHandler = { [weak self] (isOn) in
guard let strongSelf = self else {
return
}
strongSelf.viewModel.showOnlyVegMenu(shouldShowVeg: isOn)
(venueDetailVMItems as! VenueInfoViewModel).headerSection.isVeg = isOn. //Cannot assign to immutable expression of type 'Bool'
strongSelf.tableView.reloadData()
}
headerView.addSubview(headerCell)
break
}
return headerView
}
答案 0 :(得分:1)
结构是字段的集合;如果特定结构实例是可变的,则其字段将是可变的;如果实例是不可变的,则其字段将是不可变的。因此,必须准备一种结构类型,以使任何特定实例的字段都是可变或不变的。
请检查this
因此,请尝试将 let 更改为 var
确保arrayDataSource
是可变用户 var ,而不是 let
var arrayDataSource = [VenueInfoViewModel]()
答案 1 :(得分:1)
结构是值类型,因此每次分配结构时,它都会创建一个副本。您将其视为参考类型。剥离所有as!
的投射,您要做的是:
let value = array[index]
value.someBool = true
reloadData()
即使值是可变的(可能是可变的),也不会做任何事情。 value
是array[index]
的副本,而不是对其的引用。如果希望将其用作引用,则需要将其设为引用类型(一个类)。
您已经使用了协议和“类型”标识符,我认为您真正想要的是带有关联数据的枚举:
enum VenueDetail {
case veueInfoInfo(VenueInfoViewModel)
}
有了这个,您就摆脱了所有危险而复杂的as!
投射。
但是所有这些并不能真正改变您所描述的问题。无论哪种方式(使用协议或枚举),您都需要做的是:
var value = array[index]
// change value the ways you want; set the bool, etc.
array[index] = value
答案 2 :(得分:-1)
在苦苦挣扎之后,我只是在viewModel
中创建了一个方法,该方法删除了类型为.venueInfo
的数组中的对象并重新加载,我知道它的种类,但是暂时没有选择。万一有人发现更好的方法,真的很感激
func changeHeaderSwitch(isVeg: Bool) {
arrayDataSource.removeAll { (venueDetailVMItems) -> Bool in
return venueDetailVMItems.type == .veueInfoInfo
}
if var getVenueDetails = self.venueDetails {
getVenueDetails.isVeg = isVeg
let vmType = VenueInfoViewModel(headerSection: getVenueDetails, arrayMenuInfo: [])
arrayDataSource.append(vmType)
}
}