Creazione di un oggetto Objective-C che avvolge un altro oggetto con la stessa interfaccia - problemi di KVC / KVO

StackOverflow https://stackoverflow.com/questions/3568819

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?

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top