2010-07-16 9 views
29

Méthode swizzling fonctionne très bien pour les méthodes d'exemple. Maintenant, j'ai besoin de balayer une méthode de classe. Une idée de comment le faire?Comment faire pour swizzle une méthode de classe sur iOS?

Essayé cela, mais il ne fonctionne pas:

void SwizzleClassMethod(Class c, SEL orig, SEL new) { 

Method origMethod = class_getClassMethod(c, orig); 
Method newMethod = class_getClassMethod(c, new); 

if(class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) 
    class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod)); 
else 
    method_exchangeImplementations(origMethod, newMethod); 
} 

Répondre

53

Turns, je n'étais pas loin. Cette implémentation fonctionne pour moi:

void SwizzleClassMethod(Class c, SEL orig, SEL new) { 

    Method origMethod = class_getClassMethod(c, orig); 
    Method newMethod = class_getClassMethod(c, new); 

    c = object_getClass((id)c); 

    if(class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) 
     class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod)); 
    else 
     method_exchangeImplementations(origMethod, newMethod); 
} 
+0

Mmm ... Disons que nous avons plutôt fait 'Class cc = object_getClass ((id) c)'. Il est compréhensible que vous ayez besoin d'ajouter la méthode 'cc', mais pourquoi avez-vous pris la méthode de classe' cc'? N'êtes-vous pas censé obtenir la méthode de classe de 'c'? Je suis confus ... – Yuji

+0

Yuhi, tu as raison, j'ai changé le code pour faire la résolution de la méthode sur la classe d'origine, pas la méta-classe. La vieille solution a fonctionné aussi bien que je n'ai pas vraiment dérangé. –

+0

Mon mauvais. J'ai mal saisi object_getClass dans objc_getClass. Je vais supprimer ma réponse dans une seconde. –