Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
import Cocoa
import PlaygroundSupport
let center = NotificationCenter.default
struct NotificationDescriptor<A> {
let name: Notification.Name
let convert: (Notification) -> A
}
struct PlaygroundPayload {
let page: PlaygroundPage
let needsIndefiniteExecution: Bool
}
let playgroundNotification = NotificationDescriptor<PlaygroundPayload>(name: Notification.Name("PlaygroundPageNeedsIndefiniteExecutionDidChangeNotification"), convert: { note in
let page = note.object as! PlaygroundPage
let needsIndefiniteExecution = note.userInfo!["PlaygroundPageNeedsIndefiniteExecution"] as! Bool
return PlaygroundPayload(page: page, needsIndefiniteExecution: needsIndefiniteExecution)
})
extension NotificationCenter {
func addObserver<A>(forDescriptor d: NotificationDescriptor<A>, using block: @escaping (A) -> ()) -> Token {
let t = addObserver(forName: d.name, object: nil, queue: nil, using: { note in
block(d.convert(note))
})
return Token(token: t, center: self)
}
}
class Token {
let token: NSObjectProtocol
let center: NotificationCenter
init(token: NSObjectProtocol, center: NotificationCenter) {
self.token = token
self.center = center
}
deinit {
center.removeObserver(token)
}
}
var token: Token? = center.addObserver(forDescriptor: playgroundNotification, using: { print($0) })
PlaygroundPage.current.needsIndefiniteExecution = true
token = nil
PlaygroundPage.current.needsIndefiniteExecution = false
// See also: https://talk.objc.io
//
// And: https://www.objc.io/blog/2015/01/19/functional-snippet-16-typed-notification-observers/ (for your own notifications)
@chriseidhof

This comment has been minimized.

Show comment
Hide comment
@chriseidhof

chriseidhof Nov 24, 2016

An answer to the (very good) question about receiving notifications during deinit:

I managed to test this. Deinitialization / Deallocation happens in phases. First, the instance is set to nil (but not yet deinited/deallocated). Then, all the properties are set to nil. If a notification happens during that time, it will access the weak reference and see nil for self. Finally, the deinits are called (first for the object, then for its properties).

It's not that hard to test this yourself, and a very useful exercise.

Owner

chriseidhof commented Nov 24, 2016

An answer to the (very good) question about receiving notifications during deinit:

I managed to test this. Deinitialization / Deallocation happens in phases. First, the instance is set to nil (but not yet deinited/deallocated). Then, all the properties are set to nil. If a notification happens during that time, it will access the weak reference and see nil for self. Finally, the deinits are called (first for the object, then for its properties).

It's not that hard to test this yourself, and a very useful exercise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment