2010-11-04 3 views
15

Est-il possible de définir vos propres opérateurs de chemin clés, tels que @avg, @sum, etc ...Définir vos propres opérateurs de chemin clé dans le cacao

+2

Je dois continuer à lutter contre l'envie d'envoyer des questions de «cacao» sur le site de cuisson ... –

+2

+1 c'est une question vraiment fascinante; Un que je n'ai jamais pensé à demander, mais celui qui a révélé des informations vraiment intéressantes. Merci d'avoir posé la question! –

Répondre

14

Réponse courte: Un peu. Vous pouvez ignorer valueForKeyPath: pour intercepter votre opérateur personnalisé ou passer à super, mais cela peut poser problème (je laisserai l'explication à cet exercice au lecteur). Réponse longue: Oui, mais cela dépend d'un comportement privé (pas d'API privée).

Après une introspection soignée de NSArray, j'ai trouvé des méthodes privées:

_distinctUnionOfSetsForKeyPath: 
_distinctUnionOfObjectsForKeyPath: 
_distinctUnionOfArraysForKeyPath: 
_unionOfSetsForKeyPath: 
_unionOfArraysForKeyPath: 
_unionOfObjectsForKeyPath: 
_minForKeyPath: 
_maxForKeyPath: 
_countForKeyPath: 
_avgForKeyPath: 
_sumForKeyPath: 

Eh bien, propre! Ces méthodes semblent correspondre aux opérateurs que vous pouvez utiliser avec des collections: @sum, @min, @max, @distinctUnionOfObjects, etc. Le @ a été remplacé par un trait de soulignement et nous avons ajouté ForKeyPath:. Il semblerait donc que nous pouvons créer une nouvelle méthode pour correspondre à la signature appropriée et nous sommes prêts à partir.

Alors:

@interface NSArray (CustomOperator) 

- (id) _fooForKeyPath:(NSString *)keyPath; 

@end 

@implementation NSArray (CustomOperator) 

- (id) _fooForKeyPath:(NSString *)keyPath { 
    //keyPath will be what comes after the keyPath. In this example, it will be "self" 
    return @"Hello world!"; 
} 

@end 

NSArray * array = [NSArray arrayWithObjects:@"1", @"2", @"3", nil]; 
NSLog(@"%@", [array valueForKeyPath:@"@foo.SELF"]); //logs "Hello world!" 

Il fonctionne, mais je ne suis pas sûr que je me fierais à ce sujet, car il repose sur un détail de mise en œuvre qui pourrait changer à l'avenir.

+2

Remplacer '-valueForKey:' à la place, bien que je le ferais. Lisez les documents sur la façon dont NSDictionary l'implémente. –

+1

@Mike à long terme, il est probablement plus stable, mais le problème avec le remplacement est que ces opérateurs ne sont généralement utiles que sur les collections, et les collections de sous-classes sont un peu nulles. :( –

+1

Belle trouvaille Dave! Cependant, il semble un bi fragile comme vous l'avez dit.Pourquoi pensez-vous que l'override valeurForKeyPath: est plus dangereux? – cfischer

0

Il est possible en redéfinissant valueForKeyPath: et de faire votre propre logique personnalisée là-dedans, mais il n'y a pas de support pour cela.

Questions connexes