Can't make subclass of NSNotification with Generic payload
object. Getting either runtime error or compile error (see comments in code below). Is it even possible with Swift 2.1? Any ideas appreciated. Thanks!
Runtime error because NSNotification is abstract class (class cluster).
Compile error because designated initializer should be used.
public class Notification<T: Any>: NSNotification {
private var _name: String
private var _object: AnyObject?
private var _payload: T?
public override var name: String {
return _name
}
public override var object: AnyObject? {
return _object
}
public var payload: T? {
return _payload
}
/// Always nil. Use payload
public override var userInfo: [NSObject : AnyObject]? {
return nil
}
/// Change to false to "swap" implementation
#if true
init(name: String, object: AnyObject? = nil, payload: T? = nil) {
_name = name
_object = object
_payload = payload
/*
Runtime error:
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason:
'*** initialization method -initWithName:object:userInfo:
cannot be sent to an abstract object of class
_TtGC14__lldb_expr_1612NotificationSS_:
Create a concrete instance!'
*/
super.init(name: name, object: object, userInfo: nil)
}
#else
convenience init(name: String, object: AnyObject? = nil, payload: T? = nil) {
self.init()
_name = name
_object = object
_payload = payload
}
init() {
/// compiler error:
/// must call a designated initializer of the superclass
/// But using designated initializer cause runtime error listed above.
super.init()
}
#endif
}
let n = Notification<String>(name: "xyz", payload: "Hello")
From the docs, emphasis mine:
You can subclass
NSNotification
to contain information in addition to the notification name, object, and dictionary. This extra data must be agreed upon between notifiers and observers.
NSNotification
is a class cluster with no instance variables. As such, you must subclassNSNotification
and override the primitive methodsname
,object
, anduserInfo
. You can choose any designated initializer you like, but be sure that your initializer does not call[super init]
.NSNotification
is not meant to be instantiated directly, and itsinit
method raises an exception.
There's no way subclass NSNotification
from Swift code right now, as Swift has no concept of "uninitializable classes" and requires that all subclasses invoke their superclass's init
(which, in this case, is the wrong thing to do).
You'll have to write the subclass in Objective-C and bridge it into your Swift code.
Unfortunately, even though you can declare your Objective-C class generic, that information is lost in the bridging process. From the docs:
Aside from these Foundation collection classes, Objective-C lightweight generics are ignored by Swift. Any other types using lightweight generics are imported into Swift as if they were unparameterized.
:(
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With