Lets talk about The Singleton in Swift

Sellen Wei
2 min readNov 16, 2018

--

This is some note while I studying singleton in swift:

Above is how we implement an singleton object. Make sure init function is mark as private so no one could call it outside from this class.

Now we generate a main function to test singleton object is generated and get, how to make sure there is only one instance generated in db and db2?? Well, we print out “SingletonDatabase.instanceCount” because it will increase if init function have been called twice.

Well, the major issue cause developer headache is: Testability Issue.

Let say we have a function called “SingletonRecordFinder”, and want to test the function inside it “totalPopulation”

Here is a test we generate for totalPopulation(), it looks good though, but wait second, what is unit test? unit test is using fake data and test function logic only, but in this code we are not only test function logic, we also test the population number (data) in this singleton. The bad news is, if we change database for this singleton, this unit test definitely will fail. Even the function we are testing has nothing wrong with it.

Ok, Now we need dependency injection to help us do this test correctly.

If you do not know what is dependency injection, I have another article explain this in an easy way: What is Dependency Injection?

Now let start to use dependency injection to do some test, the major idea here is we generate a fake database called “dummyDataBase”, and whenever we want to use the data in SingletonDatabase, we use DummyDatabase as dependency injection, here is some preparation work:

And then we modify singletonRecordFinder in this way, now database is an object ready for injection, and “totalPopulation” function will use whatever database passed in (in init) to calculate population.

so the unit test will looks like this, I put old unit test here so you could see the difference, in the new unit test, result will not change unless we change dummyDataBase. This will help reduce the test dependency on real singleton data base.

Last thing: Monostate sometimes may behave like singleton when called outside of class, but it is not a good way to communicate with customer. Google for more if you do not know what is monostate. Tips: all variable in this class is static variable.

What issue may lazy instantiated singleton facing when called in Multi-threading places?

OK, now let’s talk about lazy instantiation. In swift if we use :

static let sharedInstance = Singleton()

This will guarantee for lazily initialized only once. Unlike the traditional way objective c used to instantiate (may have issue if not sync) swift provide a more safe way to solve the muti-thread issue.

--

--