使用存储在参数中的类型转换对象
Cast object using type stored in a parameter
如何使用类型(存储在参数中)转换对象?
示例:
假设我有一个简单的 enum
像这样:
enum SettingsAction {
case contactUs
var cellType: UITableViewCell.Type {
return TitleSettingsTableViewCell.self
}
}
然后我尝试用 cellType
创建一个对象,像这样:
let settingsAction = SettingsAction.contactUs
let cellType = settingsAction.cellType
let cell = tableView.dequeueReusableCell(withIdentifier: "\(cellType)", for: indexPath) as! cellType
我收到以下错误:
Cannot find type 'cellType' in scope
似乎无法使用参数进行转换,导致一些奇怪的预编译错误。
是否有正确的方法来实现我正在尝试的目标?
试试这样的 -
enum SettingsAction {
case contactUs
func cellForRow(at indexPath: IndexPath, in tableView: UITableView) -> UITableViewCell {
switch self {
case .contactUs:
return tableView.dequeueReusableCell(withIdentifier: "TitleSettingsTableViewCell", for: indexPath) as! TitleSettingsTableViewCell
}
}
}
更新
Swift 不允许您使用存储在仅在运行时可用的变量中的 Type
信息。在编译时类型推断需要此信息。
您必须以某种方式放弃灵活性。
这是解决相同问题的另一种尝试 - 远非理想 - 它确实可以满足此用例的需要。
class UserInfoTableViewCell: UITableViewCell {
var userProperty: Bool = false
}
class ContactUsTableViewCell: UITableViewCell {
var contactProperty: Bool = false
}
class LegalTableViewCell: UITableViewCell {
var legalProperty: Bool = false
}
class SettingsCellCreator<T: UITableViewCell> {
func cellForRow(at indexPath: IndexPath, in tableView: UITableView) -> T {
tableView.dequeueReusableCell(withIdentifier: "\(T.self)", for: indexPath) as! T
}
}
private let userInfoCellCreator = SettingsCellCreator<UserInfoTableViewCell>()
private let contactUsCellCreator = SettingsCellCreator<ContactUsTableViewCell>()
private let legalCellCreator = SettingsCellCreator<LegalTableViewCell>()
class ViewController: UIViewController, UITableViewDataSource {
enum CellType {
case userInfo
case contactUs
case legal
}
private var rows: [CellType] = [
.userInfo,
.contactUs,
.contactUs,
.legal,
.legal
]
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
rows.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch rows[indexPath.row] {
case .userInfo:
let cell = userInfoCellCreator.cellForRow(at: indexPath, in: tableView)
cell.userProperty = true
return cell
case .contactUs:
let cell = contactUsCellCreator.cellForRow(at: indexPath, in: tableView)
cell.contactProperty = true
return cell
case .legal:
let cell = legalCellCreator.cellForRow(at: indexPath, in: tableView)
cell.legalProperty = true
return cell
}
}
}
在 Swift 中,必须给出向下转换 as
和类型检查 is
运算符的右侧,以代替这些运算符的使用。
因此,不可能使用存储或计算的元类型对对象进行强制转换或类型检查。
如何使用类型(存储在参数中)转换对象?
示例:
假设我有一个简单的 enum
像这样:
enum SettingsAction {
case contactUs
var cellType: UITableViewCell.Type {
return TitleSettingsTableViewCell.self
}
}
然后我尝试用 cellType
创建一个对象,像这样:
let settingsAction = SettingsAction.contactUs
let cellType = settingsAction.cellType
let cell = tableView.dequeueReusableCell(withIdentifier: "\(cellType)", for: indexPath) as! cellType
我收到以下错误:
Cannot find type 'cellType' in scope
似乎无法使用参数进行转换,导致一些奇怪的预编译错误。
是否有正确的方法来实现我正在尝试的目标?
试试这样的 -
enum SettingsAction {
case contactUs
func cellForRow(at indexPath: IndexPath, in tableView: UITableView) -> UITableViewCell {
switch self {
case .contactUs:
return tableView.dequeueReusableCell(withIdentifier: "TitleSettingsTableViewCell", for: indexPath) as! TitleSettingsTableViewCell
}
}
}
更新
Swift 不允许您使用存储在仅在运行时可用的变量中的 Type
信息。在编译时类型推断需要此信息。
您必须以某种方式放弃灵活性。
这是解决相同问题的另一种尝试 - 远非理想 - 它确实可以满足此用例的需要。
class UserInfoTableViewCell: UITableViewCell {
var userProperty: Bool = false
}
class ContactUsTableViewCell: UITableViewCell {
var contactProperty: Bool = false
}
class LegalTableViewCell: UITableViewCell {
var legalProperty: Bool = false
}
class SettingsCellCreator<T: UITableViewCell> {
func cellForRow(at indexPath: IndexPath, in tableView: UITableView) -> T {
tableView.dequeueReusableCell(withIdentifier: "\(T.self)", for: indexPath) as! T
}
}
private let userInfoCellCreator = SettingsCellCreator<UserInfoTableViewCell>()
private let contactUsCellCreator = SettingsCellCreator<ContactUsTableViewCell>()
private let legalCellCreator = SettingsCellCreator<LegalTableViewCell>()
class ViewController: UIViewController, UITableViewDataSource {
enum CellType {
case userInfo
case contactUs
case legal
}
private var rows: [CellType] = [
.userInfo,
.contactUs,
.contactUs,
.legal,
.legal
]
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
rows.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch rows[indexPath.row] {
case .userInfo:
let cell = userInfoCellCreator.cellForRow(at: indexPath, in: tableView)
cell.userProperty = true
return cell
case .contactUs:
let cell = contactUsCellCreator.cellForRow(at: indexPath, in: tableView)
cell.contactProperty = true
return cell
case .legal:
let cell = legalCellCreator.cellForRow(at: indexPath, in: tableView)
cell.legalProperty = true
return cell
}
}
}
在 Swift 中,必须给出向下转换 as
和类型检查 is
运算符的右侧,以代替这些运算符的使用。
因此,不可能使用存储或计算的元类型对对象进行强制转换或类型检查。