2014-06-09 16 views
12

Quando sto attuano il protocollo di NSCoding in Objective-C, vorrei utilizzare NSStringFromSelector(@selector(name)) per ottenere il percorso della chiave di una proprietà, come qui di seguitoCompile percorso della chiave di tempo il check-in Swift

- (void)encodeWithCoder:(NSCoder *)aCoder { 
    [aCoder encodeObject:self.accountName forKey:NSStringFromSelector(@selector(accountName))]; 
    [aCoder encodeObject:self.userId forKey:NSStringFromSelector(@selector(userId))]; 
} 

- (id)initWithCoder:(NSCoder *)aDecoder { 
    self = [super init]; 
    if (self) { 
     _accountName = [aDecoder decodeObjectForKey:forKey:NSStringFromSelector(@selector(accountName))]; 
     _userId = [aDecoder decodeObjectForKey:forKey:NSStringFromSelector(@selector(userId))]; 
    } 
    return self; 
} 

Mi piace questo perché impedisce l'errata digitazione senza la necessità di definire molte costanti di stringa e ricevo avvertenze se le mie proprietà vengano rinominate. Ma non riuscivo a trovare un modo per farlo in Swift, qualche idea?

+0

attendere la riflessione API –

risposta

1

In Swift, i selettori sono stringhe. (Bene, c'è il tipo Selector, ma che converte in modo trasparente da e verso String.) Quindi puoi omettere NSStringFromSelector e @selector e usare solo una stringa letterale.

Se stai cercando di introspettare i nomi delle tue proprietà ... è un po 'più difficile. L'utilizzo di reflect() in un'istanza della classe restituisce un oggetto di tipo Mirror. (Incolla uno di quei simboli nel tuo campo da gioco e fai clic su cmd per ottenere le dichiarazioni nella "libreria" standard della libreria.) Puoi usarlo per percorrere l'elenco delle proprietà della classe.

Ciò renderebbe il metodo di "codificare tutto" guarda qualcosa di simile:

func encodeWithCoder(coder: NSCoder!) { 
    let mirror = reflect(self) 
    let (accountNameKey, _) = mirror[0] 
    let (userIdKey, _) = mirror[1] 

    coder.encodeObject(accountName, forKey: accountNameKey) 
    coder.encodeObject(userId, forKey: userIdKey) 
} 

Non è l'ideale, dal momento che è necessario conoscere l'ordine delle definizioni delle proprietà. Ma potrebbe essere migliorato ...

+8

Il problema è che ha bisogno della sintassi '@selector()' per la verifica. Se mette una stringa, può avere un errore di battitura e non avrà un avvertimento. –

+0

Il vero problema è che Swift non ha ancora sostituito direttamente questo comportamento. –

+1

A partire da swift 2.2, è possibile utilizzare una nuova sintassi speciale per ottenere un selettore. Ad esempio 'let sel = #selector (UIView.insertSubview (_: at :)) // produce il selettore" insertSubview: atIndex: "'. Riferimento: https://github.com/apple/swift-evolution/blob/master/proposals/0022-objc-selectors.md – Mrwerdo

Problemi correlati