Creazione di un oggetto Objective-C che avvolge un altro oggetto con la stessa interfaccia - problemi di KVC / KVO
-
01-10-2019 - |
Domanda
Ho bisogno di creare un oggetto in una gerarchia di classi che avvolge un oggetto da un altro. Entrambi hanno interfacce molto simili, e mi piacerebbe avere automaticamente il mio involucro inoltrare messaggi non riconosce al suo obiettivo in luogo di attuazione delle sue proprietà. Ho ottenuto questo al lavoro utilizzando qualcosa di simile:
- (id)forwardingTargetForSelector:(SEL)sel { if ([self.wrappedObject respondsToSelector:sel]) return self.wrappedObject; return self; }
Ma questo non funziona per la codifica valore-chiave. Come posso fare per avere il mio involucro implementare valore-chiave di codifica in modo che utilizza le proprietà del suo oggetto avvolto?
Soluzione
Si dovrà valueForKey:
sovrascrittura e setValue:forKey:
. Un esempio:
- (id)valueForKey:(NSString *)key {
if (/* wrapped object has key */)
return [self.wrappedObject valueForKey: key];
else
return [super valueForKey: key];
}
La parte difficile sarà quello di determinare le chiavi dell'oggetto avvolto non attuano. Il modo più semplice è quello di codificare loro, ma che non è troppo bello. Se si vuole fare è molto generico, farete qualcosa usando le API di riflessione di Objective-C. Qui ci sono due idee:
-
Tutte le proprietà sono in realtà dichiarati proprietà. , è possibile utilizzare la funzione di runtime class_getProperty a controllare l'esistenza e, facoltativamente estrarre informazioni aggiuntive. Il controllo potrebbe quindi simile a questa:.
if (class_getProperty([self.wrappedObject class], [key UTF8String]) != nil) {...}
-
Le proprietà potrebbe anche avere solo funzioni di accesso. Poi si dovrebbe costruire i selettori dalla chiave e l'uso
[self.wrappedObject respondsToSelector: ...]
proprio come avete fatto prima. Il nome del getter è la chiave, più due punti. Il problema con questo, però, è proprietà che hanno diverso nome getter / setter. La prima opzione è sicuramente il migliore.