使用存储在参数中的类型转换对象

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 运算符的右侧,以代替这些运算符的使用。

因此,不可能使用存储或计算的元类型对对象进行强制转换或类型检查。