2010-12-10 4 views
2

Sur un projet passé (pré-iOS 4.0), j'ai écrit la méthode de la catégorie suivante sur NSSortDescriptor:Est-il possible d'avoir une catégorie Objective-C chargée seulement si la méthode n'existe pas déjà?

+ (id)sortDescriptorWithKey:(NSString *)key ascending:(BOOL)ascending; 

Quand Apple a publié le SDK iOS 4.0, il inclus exactement la même méthode (qui ne doute exactement la même chose). Est-il possible d'écrire une catégorie qui est seulement ajoutée au runtime soit si vous exécutez une version de système d'exploitation particulière, ou probablement plus au point, s'il n'y a pas déjà une méthode déclarée avec la même signature?

Dans ce cas, il est probablement sûr de remplacer la méthode sortDescriptorWithKey:ascending: par une catégorie, ce qui donnera à la fois iOS 3 et iOS 4, puisque ma version fera presque certainement la même chose. Je préférerais ne pas jouer avec les méthodes définies par le système si possible, en raison de la possibilité (improbable) de casser les choses dans les cas limites.

Répondre

4

Pas directement, non.

La façon dont je recommande de le faire serait d'avoir un my_sortDescriptorWithKey: qui peut alors vérifier si la classe répond à sortDescriptorWithKey: et l'utilise si c'est le cas, sinon utilisez votre propre implémentation.

+0

Je ne dis pas que c'est forcément une bonne idée pour le code de production, mais serait-il possible de le faire en utilisant les fonctions 'runtime.h'? Dites d'utiliser 'class_addMethod' après avoir vérifié si une telle méthode existe déjà en utilisant quelque chose comme' class_getClassMethod'? –

+0

Oui, comme Jeff a montré que c'est aussi possible, mais j'essaie d'éviter les hacks d'exécution quand c'est possible. –

5

La réponse de Joshua va bien travailler, mais si vous voulez obtenir vraiment fantaisie, vous pouvez utiliser la nature dynamique de l'Objective-C pour modifier la classe NSSortDescriptor à votre goût:

#import <objc/runtime.h> 

SEL theSelector = @selector(sortDescriptorWithKey:ascending:); 

if (! [NSSortDescriptor instancesRespondToSelector:theSelector]) { 
    class_addMethod([NSSortDescriptor class], 
        theSelector, 
        (IMP)mySortDescriptorWithKey, 
        "@@:@B"); 
} 

Bien sûr, qui dépend d'une fonction C:

id mySortDescriptorWithKeyAscending(id self, SEL _cmd, NSString *key, BOOL ascending) { 
    // Put your code here. 
} 

AVERTISSEMENT: Je n'ai pas essayé de compiler tout cela.

DISCLAIMER II: Cela peut être mal vu par Apple en termes de soumission App Store.

+0

Lorsque j'aurai accès à un appareil iOS3, j'essaierai cette suggestion et je ferai rapport! –

Questions connexes