在变量中存储类型?

时间:2018-04-13 13:46:29

标签: ios swift types

所以我想知道是否可以在变量中保存一个类型,稍后将在同一个函数中使用。

我的代码如下:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let object = array.item(at: indexPath.row) else {
        fatalError("Could not retrieve the table object")
    }

    if object.displayOnLeft {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: LeftSidedCell.className, for: indexPath) as? LeftSidedCell else {
            fatalError("Could not dequeue the left sided cell")
        }
        cell.object = object
        return cell
    } else {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: RightSidedCell.className, for: indexPath) as? RightSidedCell else {
             fatalError("Could not dequeue the right sided cell")
        }
        cell.object = object
        return cell
    }
}

但我认为这实际上非常笨重,因为if和else中的内容基本相同,只是单元格的类型不同。

我理想地想要一种基本上算法:

var type
if object.displayOnLeft {
   type = LeftSidedCell
} else {
   type = RightSidedCell
}

//Dequeue Cell with type

我知道这里有一些问题,首先,我不能在没有类型的情况下声明变量,并且我不确定首先将它分配给哪个类型。其次,检索类的类型也没有多少成果。

我已经尝试将其存储为Object中的属性,并将其返回到我的自定义对象中的此类函数以及以下的一些变体中:

func getTypeOfCell<T:TranslationCellProtocol>() -> T.Type {
    if displayOnLeft {
        return LeftSidedCell.self
    } else {
        return RightSidedCell.self
    }
}

无论如何,我不确定这是否可能,或者我是否对某个概念有一个基本的误解,但任何帮助都会非常感激。

谢谢。

3 个答案:

答案 0 :(得分:2)

首先,编写一个实现className()方法的协议(或者您将用于两个单元类的任何方法和属性)并使两个单元类都符合它

protocol YourCellProtocol {
    var object : YourObjectClass? { get set }
    static func className() -> String
}

class LeftSidedCell : YourCellProtocol {...)
class RightSidedCell : YourCellProtocol {...}

然后你就可以做那样的事了

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let object = array.item(at: indexPath.row) else {
        fatalError("Could not retrieve the table object")
    }

    var type : YourCellProtocol.Type
    if object.displayOnLeft {
        type = LeftSidedCell.self
    } else {
        type = RightSidedCell.self
    }

    let cell = tableView.dequeueReusableCell(withIdentifier: type.className, for: indexPath)
    if let yourCell = cell as? YourCellProtocol
    {
        yourCell.object = object
    }

    return cell
}

答案 1 :(得分:2)

只要LeftSidedCell和RightSidedCell有一个共同的超类 - 比如MySidedCell - 你可以将它们存储在MySidedCell.Type类型的变量中:

let cellType : MySidedCell.Type = LeftSidedCell.self

稍后您可以使用==测试该值,以查看它是哪种单元格类型。

if cellType == LeftSidedCell.self {

答案 2 :(得分:1)

请注意,通过这么多可选检查和fataError次调用,您会堵塞代码。在调用cellForRow时,您应该已经确定数据源是正确的。因此,此时无需选择性地展开您的数据和表格视图单元格,因为如果数据不正确,应用程序将会崩溃。

E.g。检查您的数组是否没有项目或项目在调用numberOfRowsInSection之前是否有效无效,如果您的数据不正确,则返回0项目数并且cellForRow将无法使用该错误数据进行调用。

关于代码清洁,这对我有用:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let object = array[indexPath.row]
    let cell: UITableViewCell

    if object.displayOnLeft {
        cell = tableView.dequeueReusableCell(withIdentifier: "LeftSidedCellIdentifier", for: indexPath) as! LeftSidedCell
    } else {
        cell = tableView.dequeueReusableCell(withIdentifier: "RightSidedCellIdentifier", for: indexPath) as! RightSidedCell
    }

    cell.object = object
    return cell
}