Exploring Design Patterns used by Apple on iOS
Design Patterns are a crucial part of Software design, they provide a solution to commonly occurring problems.
Apple uses these patterns all over iOS frameworks. In this article, we will be discussing how design patterns are used in the internal Apple APIs and how you can benefit from these implementations.
We use iOS frameworks like UIKit
CoreLocation
CoreBluetooth
and many others in our day to day development. Components like UITableView
UIStackView
all are written using a great reusable design from apple.
There are many Design patterns that apple used throughout the development of their kits. Let us try to Explore some of these patterns and see how we could implement them.
Object Pool
The Object Pool is a pattern that re-uses a set of initialized objects.
When a client of the pool requests an object, a pool will return an actual item that is ready to be reused rather than creating a new instance. When the client has finished using the object it returns the object to the pool so it can be reused at a later time.
Object pools are used for performance since objects obtained from and returned to a pool are not actually created or destroyed at this time. Therefore saving lots of performance.
UITableView
can provide us with a great way to understand usage and implementation of object pool pattern.
The way that UITableView
works is that it takes the cells that are pushed offscreen and then reuses them for the upcoming cells.
Swift Implementation of Object Pool
Let us try to provide an object pool implementation for iOS.
Firstly We need to create a protocol that we can use to constrain our generic pool items. Since we are going to provide reusable cells for a table view, let’s name it Reusable
We can add prepareForReuse
to protocol and call it when the element gets reused from the pool to provide needed cleanup for the object before it appears again on the screen.
A UITableViewCell
then would be simply a UIView
that conforms to Reusable
Let us start implementing our Object responsible for pooling like following:
Our Object Pool Class needs a factory function that knows how to create a new generic item.
We need maxElementCount
variable that table view will use to provide the maximum number of cells that will be displayed on the screen at the same time. Since iOS already has a delegate for the number of items in a section together with heightForRowInSection
providing this value will be easy.
In the Object Pool we need two methods one is to draw an item and one to release the object to be reused. In the example of table view we would release the cell object when the cell would go offscreen.
Let us use a simple array that holds the currently released elements and either reuse them when available or create new ones with our factory function.
When the dequeueReusableCell
function would get called thenUITableView
would simply draw an object from its pool.
Since UITableView
is simply a subclass of UIScrollView
we could easily know when a cell is offscreen, therefore we can simply release the cell object to the reusable pool.
Below is the function that gets called when the cell goes offscreen.
Singleton Pattern
The singleton pattern is a pattern used to create only one instance of a particular object. All further references to the object reference to the same underlying instance. Singletons are used when it makes sense for a single object to provide access to a global resource.
A singleton object can simply be created in swift like following
Swift Implementation of Singleton
Apple uses singletons in lots of cases some of them areNSFileManager
, NSApplication
, and inUIApplication
.
When a client asks the object for an instance, it gets a shared instance. This object is lazily created on the first request.
We can use Singletons in our code to avoid re-allocating multiple instances of an instance, therefore, saving performance. We have to be aware though that singletons may cause problems in some cases and should be used carefully and not be overused.
- Use Singleton classes for situations where it makes sense for a single object to provide access to a global resource.
- Do not forget that Singleton classes cannot be subclassed.
- Singletons can hide dependencies, generally, we should aim for software architecture that has minimal dependencies between classes.
Observer pattern
The observer pattern is used to publish object state changes. Other objects can subscribe and get notified of the changes.
Interaction can take place between objects without them needing to know about the one another, this makes subject and observers loosely coupled.
How does the Apple use observer pattern?
Notifications
Apple uses Observer pattern on NSNotificationCenter
Objects post the notifications to NSNotificationCenter by identifying the notification with a global string. Observer Object can listen to this notification and get the object changes. Posting a notification is done in a synchronous manner.
We can use inNSNotificationCenter
our code to subscribe to system notifications or publish and subscribe to custom notifications.
NSNotificationCenter
is really nice, but let us try to write a custom implementation for observer pattern in Swift so we have a deeper understanding of this pattern.
Swift Implementation Of Observer Pattern
Usage
In Conclusion
Apple Makes High Usage Of Design Patterns in iOS in all of their APIs. In this article, we have explored how they implemented these patterns and we provided implementation using swift for Object Pool, Singleton, and Observer Patterns.
Understanding Design Patterns is really important for every developer that seeks clean code and architecture. If you want to know more about design patterns and how they can be easily implemented on iOS make sure to check this article that simplifies their implementation in Swift.
I hope that you enjoyed this post and this will become useful to your code base.
Make sure to clap and share it to show your support.
If you have any questions or comments feel free to leave a note here or email me at arlindaliu.dev@gmail.com.