2010-07-16 4 views
29

El método swizzling funciona muy bien, por ejemplo, con métodos. Ahora, necesito Swizzle un método de clase. ¿Alguna idea de cómo hacerlo?¿Cómo cambiar el método de clase en iOS?

intentado esto pero no funciona:

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

Respuesta

53

Resulta que no estaba muy lejos. Esta implementación funciona para mí:

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 ... Supongamos que en su lugar hicimos 'Class cc = object_getClass ((id) c)'. Es comprensible que necesites agregar el método a 'cc', pero ¿por qué tomaste el método de clase de' cc'? ¿No se supone que debes obtener el método de clase de 'c'? Estoy confundido ... – Yuji

+0

Yuhi, tienes razón, he cambiado el código para hacer la resolución del método en la clase original, no la metaclase. La solución anterior también funcionaba, así que realmente no me molesté. –

+0

Mi mal. Escribí mal object_getClass en objc_getClass. Eliminaré mi respuesta en un segundo. –

Cuestiones relacionadas