Création d'un objet Objective-C qui enveloppe un autre objet avec la même interface - problèmes KVC / KVO

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

Question

Je dois créer un objet dans une hiérarchie de classes qui enveloppe un objet d'un autre. Ils ont tous deux interfaces très semblables, et je voudrais avoir automatiquement mon wrapper messages avant qu'il ne reconnaît pas à sa cible au lieu de mettre en œuvre ses propres propriétés. Je suis arrivé que cela fonctionne en utilisant quelque chose comme ceci:

- (id)forwardingTargetForSelector:(SEL)sel 
{
    if ([self.wrappedObject respondsToSelector:sel])
        return self.wrappedObject;

    return self;
}

Mais cela ne fonctionne pas pour le codage de la valeur de clé. Comment puis-je d'avoir mon enveloppe mise en œuvre de la valeur clé de codage d'une manière qui utilise les propriétés de son objet enveloppé?

Était-ce utile?

La solution

Vous devrez écraser valueForKey: et setValue:forKey:. Un exemple:

- (id)valueForKey:(NSString *)key {
  if (/* wrapped object has key */)
    return [self.wrappedObject valueForKey: key];
  else
    return [super valueForKey: key];
}

La partie la plus délicate sera de déterminer les clés de l'objet enveloppé n'implémentez. Le moyen facile est à coder en dur, mais ce n'est pas trop gentil. Si vous voulez le faire très générique, vous allez faire quelque chose en utilisant les API de réflexion de Objective-C. Voici deux idées:

  • Tous vos biens sont effectivement déclarés propriétés. Vous pouvez utiliser la fonction d'exécution class_getProperty pour vérifier son existence et éventuellement extraire des informations supplémentaires. Le chèque pourrait alors ressembler à ceci:. if (class_getProperty([self.wrappedObject class], [key UTF8String]) != nil) {...}

  • Votre pourrait aussi accesseurs seulement. Ensuite, vous devez construire les sélecteurs de la [self.wrappedObject respondsToSelector: ...] clé et l'utilisation comme vous le faisiez auparavant. Le nom du getter est la clé ainsi que deux points. Le problème avec cela, cependant, est des propriétés qui ont un nom différent getter / setter. La première option est sans aucun doute le meilleur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top