0% found this document useful (0 votes)
21 views5 pages

What Is A Singleton

Uploaded by

berkay.unal579
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
21 views5 pages

What Is A Singleton

Uploaded by

berkay.unal579
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 5

TABLE of CONTENTS

1.What is a Singleton?
2.Global Access
3.How to create a Singleton in Swift?
4.Resource

What Is a Singleton and How To Create One In Swift

1.What Is a Singleton?

The singleton pattern guarantees that only one instance of a class is instantiated.

If you've worked with Apple's frameworks, then chances are that you've already used
the singleton pattern. Take a look at these examples. They probably look familiar.

// Shared URL Session


let sharedURLSession = URLSession.shared

// Default File Manager


let defaultFileManager = FileManager.default

// Standard User Defaults


let standardUserDefaults = UserDefaults.standard

// Default Payment Queue


let defaultPaymentQueue = SKPaymentQueue.default()

The singleton pattern is a very useful pattern. There are times that you want to make
sure only one instance of a class is instantiated and that your application only uses
that instance. That's the primary and only goal of the singleton pattern.

The default payment queue of the StoreKit framework is a fine example. An


application should never create an instance of the SKPaymentQueue class. The
operating system uses the StoreKit framework to create a payment queue, which
your application can use. The default payment queue is accessible through the
default() class method of the SKPaymentQueue class. This is a good example of
how the singleton pattern should be applied.

2.Global Access

But the singleton pattern has a side effect that's often the true reason for adopting
the singleton pattern, global access. But having global access to the singleton object
is no more than a side effect of the singleton pattern.
Unfortunately, many developers use the singleton pattern to have easy access to the
singleton object from anywhere in their project. The default payment queue is
accessible through the default() class method. This means that any object in a
project can access the default payment queue. While this is convenient, that
convenience comes at a price.

By using singletons, you almost always sacrifice transparency for convenience. But
how much are you willing to sacrifice for that little bit of convenience? Convenience
should not be high on your priority list if you're working on a software project.

The most important drawback of the singleton pattern is sacrificing transparency for
convenience. Over time, you lose track of the objects that access the user object
and, more importantly, the objects that modify its properties.

By using singletons in your project, you start to create technical debt. Singletons
tend to spread like a virus because it's so easy to access them. It's difficult to keep
track of where they're used and getting rid of a singleton can be a refactoring
nightmare in large or complex projects.

3.How to Create a Singleton In Swift?

In this episode, I list two recipes for implementing the singleton pattern in Swift. The
first implementation shouldn't be used, though. It merely illustrates a few concepts of
the Swift language.

Global Variables

The most straightforward technique to create a singleton is by defining a global


variable.

let sharedNetworkManager = NetworkManager(baseURL: API.baseURL)

class NetworkManager {

// MARK: - Properties

let baseURL: URL

// Initialization

init(baseURL: URL) {
self.baseURL = baseURL
}

}
By defining a variable in the global namespace of the project, any object in the
module has access to the singleton object. We could, for example, access the
singleton object in the application(_:didFinishLaunchingWithOptions:) method of the
AppDelegate class.

func application(_ application: UIApplication, didFinishLaunchingWithOptions


launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
print(sharedNetworkManager)
return true
}
In Swift, global variables are initialized lazily. This means that the initializer is run the
first time the global variable is referenced.

An added benefit of Swift's approach is that the initialization is performed using the
dispatch_once function. It guarantees that the initializer is invoked only once. That's
important since you only want to initialize the singleton object once.

Using a global variable has several shortcomings. The most important problem is
cluttering the global namespace. Another downside is that the initializer of the
NetworkManager class cannot be declared private. This means that multiple
instances of the class can be instantiated. Let me show you a much better, and my
preferred, implementation in Swift.

Static Property and Private Initializer

A few years ago, Swift introduced static properties and access control to the
language. This opened up an alternative approach to implementing the singleton
pattern in Swift. It's much cleaner and elegant than using a global variable. Take a
look at the updated example.

class NetworkManager {

// MARK: - Properties

static let shared = NetworkManager(baseURL: API.baseURL)

// MARK: -

let baseURL: URL

// Initialization

private init(baseURL: URL) {


self.baseURL = baseURL
}

}
Accessing the singleton is intuitive and it clearly conveys that we're dealing with a
singleton.

func application(_ application: UIApplication, didFinishLaunchingWithOptions


launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
print(NetworkManager.shared)
return true
}
Several implementation details have changed. First, the initializer is private. It means
that only the NetworkManager class can create instances of itself. That's a significant
advantage.

Second, we declared the shared static constant property. This property gives other
objects access to the singleton object of the NetworkManager class.

It isn't necessary to mark static properties with the lazy keyword. Remember what I
said earlier, the initializer of global variables and static properties are executed lazily
by default. That's another benefit.

I want to share one more implementation of the singleton pattern. This


implementation is a bit more complex. The main difference is that the singleton
object is instantiated in a closure, allowing for a more complex initialization and
configuration of the singleton object.

class NetworkManager {

// MARK: - Properties

private static var sharedNetworkManager: NetworkManager = {


let networkManager = NetworkManager(baseURL: API.baseURL)

// Configuration
// ...

return networkManager
}()

// MARK: -

let baseURL: URL

// Initialization

private init(baseURL: URL) {


self.baseURL = baseURL
}

// MARK: - Accessors
class func shared() -> NetworkManager {
return sharedNetworkManager
}

The static property is declared private. The singleton object is accessible through the
shared() class method.

func application(_ application: UIApplication, didFinishLaunchingWithOptions


launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
print(NetworkManager.shared())
return true
}

4.Resource

https://cocoacasts.com/what-is-a-singleton-and-how-to-create-one-in-swift

You might also like