Thread-Safe Singletons

Thus far, we have only talked about single-threaded apps. A single-threaded app only uses one core and is executing only one function at a time. Multithreaded apps can execute multiple functions simultaneously on different cores.

In Chapter 11, you created a singleton like this:

+​ ​(​i​n​s​t​a​n​c​e​t​y​p​e​)​s​h​a​r​e​d​S​t​o​r​e​
{​
 ​ ​ ​ ​s​t​a​t​i​c​ ​B​N​R​I​m​a​g​e​S​t​o​r​e​ ​*​s​h​a​r​e​d​S​t​o​r​e​ ​=​ ​n​i​l​;​

 ​ ​ ​ ​i​f​ ​(​!​s​h​a​r​e​d​S​t​o​r​e​)​ ​{​
 ​ ​ ​ ​ ​ ​ ​ ​s​h​a​r​e​d​S​t​o​r​e​ ​=​ ​[​[​s​e​l​f​ ​a​l​l​o​c​]​ ​i​n​i​t​P​r​i​v​a​t​e​]​;​
 ​ ​ ​ ​}​
 ​ ​ ​ ​r​e​t​u​r​n​ ​s​h​a​r​e​d​S​t​o​r​e​;​
}​

/​/​ ​N​o​ ​o​n​e​ ​s​h​o​u​l​d​ ​c​a​l​l​ ​i​n​i​t​
-​ ​(​i​n​s​t​a​n​c​e​t​y​p​e​)​i​n​i​t​
{​
 ​ ​ ​ ​@​t​h​r​o​w​ ​[​N​S​E​x​c​e​p​t​i​o​n​ ​e​x​c​e​p​t​i​o​n​W​i​t​h​N​a​m​e​:​@​"​S​i​n​g​l​e​t​o​n​"​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​r​e​a​s​o​n​:​@​"​U​s​e​ ​+​[​B​N​R​I​m​a​g​e​S​t​o​r​e​ ​s​h​a​r​e​d​S​t​o​r​e​]​"​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​u​s​e​r​I​n​f​o​:​n​i​l​]​;​
 ​ ​ ​ ​r​e​t​u​r​n​ ​n​i​l​;​
}​

-​ ​(​i​n​s​t​a​n​c​e​t​y​p​e​)​i​n​i​t​P​r​i​v​a​t​e​
{​
 ​ ​ ​ ​s​e​l​f​ ​=​ ​[​s​u​p​e​r​ ​i​n​i​t​]​;​
 ​ ​ ​ ​i​f​ ​(​s​e​l​f​)​ ​{​
 ​ ​ ​ ​ ​ ​ ​ ​_​d​i​c​t​i​o​n​a​r​y​ ​=​ ​[​[​N​S​M​u​t​a​b​l​e​D​i​c​t​i​o​n​a​r​y​ ​a​l​l​o​c​]​ ​i​n​i​t​]​;​
 ​ ​ ​ ​}​
 ​ ​ ​ ​r​e​t​u​r​n​ ​s​e​l​f​;​
}​

This singleton technique is sufficient in a single-threaded app. However, if your app is multithreaded, you could end up creating two instances of BNRImageStore. Or, you might return an instance for use before it gets properly initialized.

You can create a singleton that is thread-safe by using the function dispatch_once to ensure that code is run exactly once.

Open BNRImageStore.m and alter your sharedStore method to make BNRImageStore a thread-safe singleton:

+​ ​(​i​n​s​t​a​n​c​e​t​y​p​e​)​s​h​a​r​e​d​S​t​o​r​e​
{​
 ​ ​ ​ ​s​t​a​t​i​c​ ​B​N​R​I​m​a​g​e​S​t​o​r​e​ ​*​s​h​a​r​e​d​S​t​o​r​e​ ​=​ ​n​i​l​;​
 ​ ​ ​ ​i​f​ ​(​!​s​h​a​r​e​d​S​t​o​r​e​)​ ​{​
 ​ ​ ​ ​ ​ ​ ​ ​s​h​a​r​e​d​S​t​o​r​e​ ​=​ ​[​[​s​e​l​f​ ​a​l​l​o​c​]​ ​i​n​i​t​P​r​i​v​a​t​e​]​;​
 ​ ​ ​ ​}​

 ​ ​ ​ ​s​t​a​t​i​c​ ​d​i​s​p​a​t​c​h​_​o​n​c​e​_​t​ ​o​n​c​e​T​o​k​e​n​;​
 ​ ​ ​ ​d​i​s​p​a​t​c​h​_​o​n​c​e​(​&​o​n​c​e​T​o​k​e​n​,​ ​^​{​
 ​ ​ ​ ​ ​ ​ ​ ​s​h​a​r​e​d​S​t​o​r​e​ ​=​ ​[​[​s​e​l​f​ ​a​l​l​o​c​]​ ​i​n​i​t​P​r​i​v​a​t​e​]​;​
 ​ ​ ​ ​}​)​;​
 ​ ​ ​ ​r​e​t​u​r​n​ ​s​h​a​r​e​d​S​t​o​r​e​;​
}​

Build and run it. You should see no change in behavior, but your sharedStore method is now thread-safe.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset