mirror of
https://github.com/signalapp/Signal-iOS.git
synced 2025-12-05 01:10:41 +00:00
Remove observeOnce method that’s not necessary
This commit is contained in:
@@ -6,18 +6,17 @@
|
||||
import Foundation
|
||||
import SignalServiceKit
|
||||
|
||||
class AppActivePrecondition: Precondition {
|
||||
private let appContext: AppContext
|
||||
struct AppActivePrecondition: Precondition {
|
||||
private let _precondition: NotificationPrecondition
|
||||
|
||||
init(appContext: AppContext) {
|
||||
self.appContext = appContext
|
||||
self._precondition = NotificationPrecondition(
|
||||
notificationName: UIApplication.didBecomeActiveNotification,
|
||||
isSatisfied: { appContext.isAppForegroundAndActive() },
|
||||
)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func waitUntilSatisfied() async -> WaitResult {
|
||||
if appContext.isAppForegroundAndActive() {
|
||||
return .satisfiedImmediately
|
||||
}
|
||||
await NotificationCenter.default.observeOnce(UIApplication.didBecomeActiveNotification)
|
||||
return .wasNotSatisfiedButIsNow
|
||||
return await self._precondition.waitUntilSatisfied()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,40 +12,6 @@ import Foundation
|
||||
// possible risk of deadlock. These methods also ensure that
|
||||
// the notifications are always fired on the main thread.
|
||||
extension NotificationCenter {
|
||||
|
||||
/// Waits until `name`/`object` is posted.
|
||||
public func observeOnce(_ name: Notification.Name, object: Any? = nil) async {
|
||||
await withCheckedContinuation { continuation in
|
||||
// Concurrency in this method is nontrivial. There are at least two
|
||||
// relevant race conditions:
|
||||
//
|
||||
// (1) Multiple threads could post a notification at the same time, and
|
||||
// this will trigger multiple callbacks, even if you call `removeObserver`
|
||||
// as quickly as possible. We guard against this with an atomic
|
||||
// compare-and-swap to set the observer to nil.
|
||||
//
|
||||
// (2) When initially registering the observer, it's possible that another
|
||||
// thread could be posting the notifiation at the same time. If the
|
||||
// notification callback happens before we've assigned the initial value to
|
||||
// the atomic observer value, we'll drop that notification. We avoid that
|
||||
// problem by ensuring that the `addObserver` call and assignment of the
|
||||
// observer happen atomically.
|
||||
//
|
||||
// Memory management in this method is also non-trivial. The observer
|
||||
// captured in the block must be set to nil to avoid leaking memory.
|
||||
let observer = AtomicOptional<NSObjectProtocol>(nil, lock: .init())
|
||||
_ = observer.map { _ in
|
||||
return addObserver(forName: name, object: object, queue: nil, using: { [weak self] notification in
|
||||
guard let observer = observer.swap(nil) else {
|
||||
return
|
||||
}
|
||||
self?.removeObserver(observer)
|
||||
continuation.resume(returning: ())
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func postOnMainThread(_ notification: Notification) {
|
||||
DispatchQueue.main.async {
|
||||
self.post(notification)
|
||||
|
||||
Reference in New Issue
Block a user