Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reinitialize static variables

Tags:

swift

I have a simple tableview within my Settings VC. There are two different cases, either the logged in user is an employee or the admin. The Admin is able to add Users to the organization, so he sees two sections with one row each (add user and log out) while a normal employee only sees one section with one row (log out). To manage the indexPaths I have these structs:

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)
        }
    }
}

Within my TableView delegate I got these Methods:

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

and

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
    }

The problem now is, when I sign out as Admin and Sign in as Employee (or vice versa), the static variables of the structs are still initialized and the fact, that the isEmployee() return value has changed doesn't matter because the variables aren't reloaded, so I have wrong amounts of cells. Is there a possibility to force the structs to reload their static variables?

like image 710
Stephan Boner Avatar asked Dec 11 '22 07:12

Stephan Boner


1 Answers

There is not a way to force the structs to reload their static stored constants, but you simply need to use static computed variables instead.

A computed variable looks like the following:

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

Computed variables are not actually stored, but computed each time you call them. This won't be a problem unless your logic takes a long time to execute, which yours shouldn't. Even though this is labeled var and not let, it will still be read-only because you have only specified a getter (you could have specified a setter with a set block below the get block).

As a shortcut, you don't need to explicitly show the get keyword and braces when you only want a getter, so you can get rid of those. You're left with:

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)
        }
    }
}

If you wanted, you could even convert indexPath to a computed variable rather than a function and it would do the same thing. A common convention in Swift is to use computed variables when no arguments are required and the logic to get the result is trivial and therefore won't take long.

like image 112
Matthew Seaman Avatar answered Jan 19 '23 15:01

Matthew Seaman