Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Swift singleton pattern sample
class Something {
/// Counter. We keep this around to prove we aren't getting new copies of `Something` - just the same one, over and
/// over again.
var _counter: Int = 0
/// Cached instance. We put the one copy we make of `Something` here, so we can keep it around, and hand it back if
/// anyone else asks for it. It's important that this is private, too.
private static var _singleton: Something? = nil
/// Constructor. Notice it's private, meaning it can only be called by other functions on `Something`.
///
/// We need to make it private to make *sure* invoking code (code that calls into this) uses `acquire` to get an
/// instance of `Something`, rather than constructing it with `Something()`.
///
/// We initialize our counter to 1 to illustrate that this ran.
///
private init() {
_counter = 1
}
/// Acquire method. This method is referred to as the "static factory method."
///
/// It is called these things because:
/// - It is "static": You call it with `Something.acquire()`, as in, you call it on the class.
/// - It is a "factory": `Something.acquire` produces instances of `Something`, which is itself. This makes this
/// method a "factory".
/// - It is a "method" because it is a function on a class.
///
public static func acquire() -> Something {
if _singleton == nil {
_singleton = Something()
} else {
_singleton!._counter = _singleton!._counter + 1 // count up each time we acquire
}
return _singleton!
}
}
/// Test the singleton. We get the singleton, and print the count.
/// Then, we re-acquire it, which would normally be a *new* object with a count of 1.
/// But the count remains at 2, because it is the *same* instance of `Something`, not a different one.
let first = Something.acquire()
assert(first._counter == 1) // true
let second = Something.acquire()
assert(first._counter == 2) // true
Something.acquire()
assert(first._counter == 3) // true
// note that we're testing on the original object here. the same is true for all copies though
assert(second._counter == 3) // true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.