objective c - Method Swizzling isEqualToString -
i'm running odd behavior when trying method swizzle isequaltostring:
on nsstring
class. here code in question:
#import <foundation/foundation.h> #import <objc/objc-runtime.h> @interface nsstring (swizzlestring) - (bool) custom_isequaltostring:(nsstring *)astring; - (nsrange)custom_rangeofstring:(nsstring *)astring; @end @implementation nsstring (swizzlestring) - (bool) custom_isequaltostring:(nsstring *)astring; { nslog(@"inside custom_isequaltostring method definition"); return [self custom_isequaltostring:astring]; } - (nsrange)custom_rangeofstring:(nsstring *)astring; { nslog(@"inside custom_rangeofstring method definition"); return [self custom_rangeofstring:astring]; } @end int main(int argc, const char * argv[]) { method m1, m2; m1 = class_getinstancemethod([nsstring class], @selector(isequaltostring:)); m2 = class_getinstancemethod([nsstring class], @selector(custom_isequaltostring:)); method_exchangeimplementations(m1, m2); m1 = class_getinstancemethod([nsstring class], @selector(rangeofstring:)); m2 = class_getinstancemethod([nsstring class], @selector(custom_rangeofstring:)); method_exchangeimplementations(m1, m2); nsstring *foo = @"foo"; // not log anything, still using isequaltostring: implementation [foo isequaltostring:@"foo"]; // not log anything, since using method implementation isequaltostring: [foo custom_isequaltostring:@"foo"]; // log because rangeofstring uses custom_rangeofstring imp [foo rangeofstring:@"foo"]; // not log because uses method implementation rangeofstring: [foo custom_rangeofstring:@"foo"]; }
isequaltostring:
, rangeofstring:
both defined in category on nsstring
called (nsstringextensionmethods)
, included rangeofstring
swizzle show i'm swizzling methods correctly , nsstring
object eliminate questions class cluster problems.
when produce assembly code above, instead of seeing normal objc_msgsend
calls instead see stuff l_objc_msgsend_fixup_isequaltostring_
. led me finding out more objective-c vtable, in seems isequaltostring:
can found:
static const char * const defaultvtable[] = { "allocwithzone:", "alloc", "class", "self", "iskindofclass:", "respondstoselector:", "isflipped", "length", "objectforkey:", "count", "objectatindex:", "isequaltostring:", "isequal:", "retain", "release", "autorelease", };
i've been digging through objective-c source , internet day on how possible somehow still able swizzle isequaltostring:
.
as you're aware, class cluster. need actual class, not public class, ask string object have:
nsstring *foo = @"foo"; m1 = class_getinstancemethod([foo class], @selector(isequaltostring:)); m2 = class_getinstancemethod([foo class], @selector(custom_isequaltostring:)); method_exchangeimplementations(m1, m2);
there's fragile alternative of using class name itself:
nsclassfromstring(@"__nscfconstantstring") nsclassfromstring(@"__nscfstring")
Comments
Post a Comment