Last active
March 22, 2018 11:52
-
-
Save danielctull/5629a04030a1a3c329b472a998c707c7 to your computer and use it in GitHub Desktop.
A small class to coalesce multiple calls to trigger a block once.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
/// This manages coalescing multiple calls per frame into a | |
/// single execution of the given block. | |
final class Coalescer { | |
private let notificationCenter: NotificationCenter | |
private let notificationQueue: NotificationQueue | |
private let notificationName = Notification.Name(rawValue: "CoalescingNotification") | |
/// Create a coalescer. | |
/// | |
/// The given block will be run once after one or more calls to | |
/// coalesce() happen in a single frame. | |
/// | |
/// - Parameter block: The block to run. | |
init(block: @escaping () -> ()) { | |
// We use our own private notification center and notification | |
// queue so as not to pollute the global default center and queue. | |
// This also means multiple Coalescers can co exist firing the same | |
// notification name, without triggering each other. | |
notificationCenter = NotificationCenter() | |
notificationQueue = NotificationQueue(notificationCenter: notificationCenter) | |
notificationCenter.addObserver(forName: notificationName, object: nil, queue: nil) { (notification) in | |
block() | |
} | |
} | |
/// Call this to trigger the execution of the block given when instantiated. | |
func coalesce() { | |
let notification = Notification(name: notificationName) | |
// We use notification queue to enqueue a notification. The | |
// coalesce mask will mean that the notification is only | |
// processed once for each individual name. | |
notificationQueue.enqueue(notification, postingStyle: .asap, coalesceMask: .onName, forModes: nil) | |
} | |
} |
I don't think you could initialise the notificationQueue
using the notificationCenter
property, so they need to be done in the init?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nice, but since the initialiser doesn't actually take any parameters used for setting the centre and the queue, why not just initialise them inline?