For Sept 2015, here\'s exactly how you make a singleton in Swift:
public class Model
{
static let shared = Model()
// ( for ocd friends ... privat
There are a few things to look out for when using this approach:
A global variable in itself is no big deal, but if you have quite some global variables, you might have trouble with autocompletion, because it will always suggest these global variables.
Another problem with global variables is that you could have another module in your application (written by you or otherwise) define the same global variable. This causes problems when using these 2 modules together. This can be solved by using a prefix, like the initials of your app.
Using global variables is generally considered bad practice.
A singleton is helpful when working with a controller, or a repository. It is once created, and it creates everything it depends on. There can be only one controller, and it opens only one connection to the database. This avoids a lot of trouble when working with resources or variables that need to be accessed from throughout your app.
There are downsides however, such as testability. When a class uses a singleton, that class' behaviour is now impacted by the singletons behaviour.
Another possible issue is thread safety. When accessing a singleton from different threads without locking, problems may arise that are difficult to debug.
You should watch out when defining global variables and working with singletons. With the appropriate care, not many problems should arise.
Functionally, these are very similar, but I'd advise using the Model.shared
syntax because that makes it absolutely clear, wherever you use it, that you're dealing with a singleton, whereas if you just have that model
global floating out there, it's not clear what you're dealing with.
Also, with globals (esp with simple name like "model"), you risk of having some future class that has similarly named variables and accidentally reference the wrong one.
For a discussion about the general considerations regarding globals v singletons v other patterns, see Global Variables Are Bad which, despite the fairly leading title, presents a sober discussion, has some interesting links and presents alternatives.
By the way, for your "OCD friends" (within which I guess I must count myself, because I think it's best practice), not only would declare init
to be private
, but you'd probably declare the whole class to be final
, to avoid subclassing (at which point it becomes ambiguous to what shared
references).
I can't see a single downside to this approach:
Model.shared.test()
doesn't really make sense if you think about it, you just want to call test, why would I need to call shared
when I just need a function.In general, setting aside the exact idiom under discussion, regarding the use of singletons:
static var shared = Model()
as a kind of macro to a singleton, as suggested in this Q, you can just define let model = Model()
which simply creates a normal global (unrelated to singletons).private init() {}
to your class, so that it only gets initialized once (noting that init
could still be called in the same file).