2010-07-16 2 views
29

Il metodo swizzling funziona alla grande, ad esempio, con i metodi. Ora, ho bisogno di swizzle un metodo di classe. Qualche idea su come farlo?Come swizzle un metodo di classe su iOS?

provato ma non funziona:

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); 
} 

risposta

53

Risulta, non ero molto lontano. Questa implementazione funziona per me:

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 ... Diciamo che invece abbiamo fatto 'Classe cc = object_getClass ((id) c)'. È comprensibile che sia necessario aggiungere il metodo a 'cc', ma perché hai preso il metodo di classe da' cc'? Non dovresti ottenere il metodo di classe da 'c'? Sono confuso ... – Yuji

+0

Yuhi, hai ragione, ho cambiato il codice per fare la risoluzione del metodo sulla classe originale, non sulla meta classe. Anche la vecchia soluzione ha funzionato, quindi non mi sono preoccupato molto. –

+0

Il mio male. Ho scritto male object_getClass in objc_getClass. Cancellerò la mia risposta tra un secondo. –