重新初始化静态变量

时间:2018-03-05 16:52:31

标签: swift

我在Settings VC中有一个简单的tableview。有两种不同的情况,登录用户是员工或管理员。管理员可以将用户添加到组织中,因此他看到两个部分,每个部分一行(添加用户和注销),而普通员工只看到一个部分有一行(注销)。要管理indexPaths,我有以下结构:

struct Indexes {
    struct AddEmployee {
        static let row = 0
        static let section = isEmployee() ? -1 : 0
        static func indexPath() -> IndexPath {
            return IndexPath(row: row, section: section)
        }
    }

    struct SignOut {
        static let row = 0
        static let section = isEmployee() ? 0 : 1
        static func indexPath() -> IndexPath {
            return IndexPath(row: row, section: section)
        }
    }
}

在我的TableView委托中,我得到了这些方法:

func numberOfSections(in tableView: UITableView) -> Int {
    return isEmployee() ? 1 : 2
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "SettingsTableViewCell", for: indexPath)
        if (indexPath == Indexes.AddEmployee.indexPath()) {
            cell.textLabel?.text = "Add Employee"
        } else if (indexPath == Indexes.SignOut.indexPath()) {
            cell.textLabel?.text = "Log out"
        }
        return cell
    }

现在的问题是,当我以Admin身份登出并以Employee身份登录(反之亦然)时,结构的static变量仍然被初始化,事实是isEmployee()返回值已更改无关紧要,因为变量未重新加载,因此我的单元格数量错误。是否有可能强制结构重新加载其静态变量?

2 个答案:

答案 0 :(得分:5)

没有办法强制结构重新加载它们的静态存储的常量,但你只需要使用静态计算变量。

计算变量如下所示:

static var section: Int {
    get {
        return isEmployee() ? -1 : 0
    }
}

计算变量实际上并未存储,而是在每次调用时计算。除非您的逻辑需要很长时间才能执行,否则这不会成为问题。虽然它标记为var而不是let,但它仍然是只读的,因为您只指定了一个getter(您可以指定一个在set下面有get块的setter {1}}阻止)。

作为一种快捷方式,当你只想要一个getter时,你不需要显式地显示get关键字和大括号,所以你可以摆脱它们。你离开了:

struct Indexes {
    struct AddEmployee {
        static let row = 0
        static var section: Int {
            return isEmployee() ? -1 : 0
        }
        static func indexPath() -> IndexPath {
            return IndexPath(row: row, section: section)
        }
    }

    struct SignOut {
        static let row = 0
        static var section: Int {
            return isEmployee() ? 0 : 1
        }
        static func indexPath() -> IndexPath {
            return IndexPath(row: row, section: section)
        }
    }
}

如果你愿意,你甚至可以将indexPath转换为计算变量而不是函数,它会做同样的事情。 Swift中的一个常见约定是当不需要参数时使用计算变量,并且获得结果的逻辑很简单,因此不会花费很长时间。

答案 1 :(得分:3)

为什么不将这些静态let更改为计算属性?

static var section: Int {
    return isEmployee() ? -1 : 0
}

现在每次引用section时,表达式isEmployee() ? -1 : 0都会被评估。

或者,您可以在用户登录时更新这些值。