Si crea una nuova classe, che ha istanze di classA e classB come variabili membro. Quindi si implementano le proprietà passando attraverso i metodi get/set.
@interface ClassAB
{
ClassA *objectA;
ClassB *objectB;
}
@property (nonatomic,strong) id propertyA;
@property (nonatomic,strong) id propertyB;
@end
@implementation ClassAB
- (id)propertyA { return objectA.propertyA; }
- (void)setPropertyA:(id)value { objectA.propertyA = value; }
- (id)propertyB { return objectB.propertyB; }
- (void)setPropertyB:(id)value { objectB.propertyB = value; }
@end
E questo è la composizione. Alcune lingue hanno una sintassi speciale per farlo (ad es., In Ruby puoi includere un insieme di metodi da una classe/modulo in un'altra), ma Objective-C non lo consente.
Una cosa che può fare fare in Objective-C è catturare i messaggi inviati all'oggetto che non hanno un metodo associato e inoltrarli a un altro oggetto. Questo trucco è utile se stai scrivendo una classe che si porrà come un'altra classe, o se ci sono molti messaggi diversi da inoltrare e non vuoi scriverli tutti manualmente.
Lo svantaggio di utilizzare l'inoltro dei messaggi è che si rinuncia a un certo controllo e può essere più difficile prevedere quando un messaggio verrà gestito dalla classe o dalla classe di inoltro. Ad esempio, se una superclasse implementa un metodo, tale metodo verrà eseguito e il codice di inoltro non verrà chiamato.
@Jackson prima di accettare questa risposta, lascia che scriva qualcosa con KVO che ti consenta di farlo in un modo più elegante. –
Credo che questa sia la soluzione migliore per la leggibilità. La soluzione di Richards è un trucco eccellente, ma metto sempre pragmatismo e leggibilità su un codice complicato. Questione di stile immagino – Slappy
@Slappy Ho usato quello che è essenzialmente l'approccio di Richard in una sola occasione - quando avevo codice esistente che non potevo modificare a cui dovevo passare un 'NSString' (che è un cluster di classe e quindi sottoclassi non è banale) a cui volevo una banda laterale di comunicazioni. Gli oggetti associati al runtime erano il principale approccio alternativo preso in considerazione, ma sentivo che il 'forwardingTargetForSelector:' (anche se per creare una sottoclasse di finzione piuttosto che comporre nel mio caso) era la soluzione più pulita e più leggibile. – Tommy