Top iOS Interview Questions on NotificationCenter
Oct 25, 2023Q1. When should we use NotificationCenter over other things in Swift?
NotificationCenter allows different parts of your application to communicate and send notifications (messages) to each other without needing to have direct references to each other.
You should use them when you have situations where one part of your app needs to notify other parts about changes or events, especially when the components involved are loosely coupled and don't need to maintain strong references to each other.
Here's an example of how to send and receive notifications:
// Define a custom notification name
extension Notification.Name {
static let newMessageReceived = Notification.Name("NewMessageReceived")
}
// Send a notification with a string
let newMessage = "Hello, World!"
NotificationCenter.default.post(name: .newMessageReceived, object: newMessage)
// Receive the notification:
NotificationCenter.default.addObserver(self,
selector: #selector(handleNewMessage(_:)),
name: .newMessageReceived,
object: nil)
Note: It's essential to remove the observer in the deinit method to avoid memory leaks.
When you have a scenario where one object needs to notify multiple other objects about an event, NotificationCenter is a good choice. Each observer can listen to the notification independently.
Q2. Why removing an observer from NotificationCenter is crucial?
When you add an object as an observer to NotificationCenter without subsequently removing it, a strong reference is created between the observer and NotificationCenter. In case of not removing this reference when the observer is no longer needed, it can lead to a retain cycle.
For example, if an observer is deallocated but remains registered, NotificationCenter will still attempt to deliver notifications to it. This can cause crashes or unwanted side effects in your app.
Q3. What is the difference between notification center and delegate in Swift?
NotificationCenter and delegates are both can be used for facilitating communication between different parts of an application, but they have distinct differences and are suitable for different scenarios.
NotificationCenter:
- They allow for a one-to-many relationship, where one object (the broadcaster) can notify multiple other objects (observers) about an event.
- Observers do not hold direct references to broadcasters. Instead, they subscribe to specific notifications and receive updates when those notifications are posted.
- They promote loose coupling between objects because observers don't need to know about the source of the notification.
- NotificationCenter is commonly used for system-wide events, such as keyboard events, app lifecycle events, and custom events that may involve multiple components of an app.
- Observers can dynamically register and unregister for notifications as needed.
Delegate:
- They establish a one-to-one relationship between two objects, typically between a source (delegating) object and a delegate object.
- The delegating object holds a reference to its delegate, and it communicates directly with the delegate by invoking its methods or properties.
- They are protocol-based, meaning the delegate object conforms to a specific protocol that defines the methods or properties the delegate must implement.
- Delegates are commonly used for communication between view controllers, custom views, and their parent controllers, such as the UITableView and UICollectionView delegates.
- Any protocol conformance issues or method signature mismatches are caught at compile time.
Q4. How do you handle multiple notifications with the same name?
When you have multiple notifications with the same name but need to differentiate between them, you can do so by inspecting the contents of the userInfo dictionary. The userInfo
dictionary allows you to attach additional data to each notification, which can be used to identify and handle them differently.
For example, you want to handle incoming chat messages using NotificationCenter
. You may have multiple chat rooms, and each chat room sends chat messages with the same notification name. You can handle them like below:
Posting Notifications:
// Simulate receiving chat messages from two different rooms
let chatMessage1: [String: Any] = ["roomID": "room1", "message": "Hello, room 1!"]
let chatMessage2: [String: Any] = ["roomID": "room2", "message": "Hi there, room 2!"]
NotificationCenter.default.post(name: .chatMessageNotification, object: nil, userInfo: chatMessage1)
NotificationCenter.default.post(name: .chatMessageNotification, object: nil, userInfo: chatMessage2)
Observing Notifications:
NotificationCenter.default.addObserver(forName: .chatMessageNotification, object: nil, queue: nil) { (notification) in
if let userInfo = notification.userInfo,
let roomID = userInfo["roomID"] as? String,
let message = userInfo["message"] as? String {
switch roomID {
case "room1": print("Received message for room 1: \(message)")
case "room2": print("Received message for room 2: \(message)")
default: print("Received message for an unknown room: \(message)")
}
}
}
This approach allows you to handle multiple notifications with the same name in a way that is contextually relevant to the data contained in the userInfo dictionary.
We hope that these interview questions will help you in your iOS interview preparation and also strengthen your basics on NotificationCenter in iOS development. We have launched our new e-book "Cracking the iOS Interview" with Top 100 iOS Interview Questions & Answers. Our book has helped more than 372 iOS developers in successfully cracking their iOS Interviews.