2015-12-01 13 views
6

Impossibile creare una sottoclasse di NSNotification con l'oggetto generico payload. Ottenere errore di runtime o errore di compilazione (vedere i commenti nel codice di seguito). È persino possibile con Swift 2.1? Qualche idea apprezzata. Grazie!Sottoclasse NSNotification con Generics in Swift 2.1

Errore di runtime perché NSNotification è una classe astratta (classe cluster).
Errore di compilazione poiché è necessario utilizzare l'inizializzatore designato.

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") 

risposta

7

From the docs, sottolineatura mia:

È possibile creare una sottoclasse NSNotification per contenere informazioni, oltre al nome di notifica, oggetto, e il dizionario. Questi dati aggiuntivi devono essere concordati tra i notificanti e gli osservatori.

NSNotification è un cluster di classi senza variabili di istanza. Pertanto, è necessario creare sottoclasse NSNotification e sovrascrivere i metodi primitivi name, object e userInfo. Puoi scegliere qualsiasi inizializzatore designato, ma assicurati che il tuo inizializzatore non chiami [super init]. NSNotification non è pensato per essere istanziato direttamente, e il suo metodo init solleva un'eccezione.

Non c'è modo sottoclasse NSNotification dal codice Swift in questo momento, come Swift non ha il concetto di "classi uninitializable" e richiede che tutte le sottoclassi invocano il loro superclasse init (che, in questo caso, è la cosa sbagliata da fare).

Dovrai scrivere la sottoclasse in Objective-C e collegarla al tuo codice Swift.

Sfortunatamente, anche se è possibile dichiarare la classe Objective-C generica, tali informazioni vengono perse nel processo di bridging. From the docs:

Oltre a queste classi di raccolta Foundation, i generici leggeri Objective-C vengono ignorati da Swift. Tutti gli altri tipi che utilizzano generici leggeri vengono importati in Swift come se fossero non parametrizzati.

:(

+1

hey ian grande lavoro – hao

Problemi correlati