Pages

GCD's dispatch_once() and Singleton Class

        Singleton is an object which is restricted to be the only instance of its class, I believe you guys are familiar with this definition. In this tutorial you will learn why and not to use it. What are it's advantages and disadvantages. And what happens when you use it with GCD's dispatch_once() function.
        
Advantages of using Singletons: 

1.) A singleton object is created only once and once created it will available through out you program/app. And it will let you access all objects defined in this class as they are global from any other class.
2.) If any class represents an entity which inherently Singular then having a single instance of a class is most appropriate.
3.) Singletons are most appropriate in situations when you have a lot of common functionality that will be used frequently, you can define that functionality at only one place.
4.) Resources allocated in Singleton are not allocated until they are needed means they are initialized Lazily. 


Disadvantages:

1.) Singletons are not Thread Safe  means  if one thread is using singleton then other should not interfere i.e locking mechanism because they are globally accessible. By thread safe I mean that they may come under most famous problem so called READER-WRITER problem i.e. at the same time one of the object from singleton is being read by some process and another process is updating value of that object.
2.) Sometimes you got so overconfident and you thought that there is only one singleton instance but there may be two or three every time you access it. And that will be most painful and dangerous situation and this is the place where dispatch_once() comes into play.

Example of how to creating Singleton: Usually some developers create singletons like below:

class var sharedInstance: MyClass {

              get {                          
                            struct Static {
                                          static let instance: MyClass? = nil
                            }

                             if  !Static.instance {
                                          Static.instance = MyClass()
                             }
                     
                             return Static.instance!
              }
}

        But this implementation is not thread safe because this implementation will not be able to deal with the situation in which multiple thread are trying to access it before it is created. Secondly, if any developer mistaken to release singleton's reference then it may create disaster if other are using it.

        Now most important thing to note is always use dispatch_once() to create Singletons which creates it just once and only once. And after this it will take care of all the house keeping of locking mechanism. Below is the implementation of singleton with dispatch_once(). It takes two parameters. The first is a predicate that tracks the "once". The second is a block to execute on the first call. Calls look like this:


class var sharedInstance: MyClass {         
             struct Static {
                        static var instance: Singleton?
                        static var token: dispatch_once_t = 0
             }
        
             dispatch_once(&Static.token) {      
                       Static.instance = Singleton()
             }                     
             return Static.instance!

}

       It is a good API for lazy initialization of shared state, whether it is a singleton instance, a cache, or anything else that needs a bit of setup the first time. This type of implementation is only needed it your app implements multi-threading environment else simple if-else would be good.

No comments:

Post a Comment