Saturday, January 21, 2012

Modify class in objc runtime

Why shall we do this? Because it is a faster way to get more power. :)

First we have to list the method in a class.

#import 

@implementation NSObject (LeakMethod)

+ (void)leakMethods:(Class)c {
            
    unsigned int count = 0;
    Method *array = class_copyMethodList( c, &count);
    DLog(@"got method count:%d", count);
    for(int i = 0 ; i < count ; i++){
        Method method = array[i];
        SEL methodselector = method_getName(method);
        const char* methodname = sel_getName(methodselector);
        unsigned int argcount = method_getNumberOfArguments(method);
        NSString *mn = [NSString stringWithCString:methodname encoding:NSASCIIStringEncoding];
        DLog(@"selector name:%@ (%d)", mn, argcount);
    }
}

@end

Use the force on UIDatePicker.

[NSObject leakMethods:NSClassFromString(@"NSDatePicker")];
2012-01-22 11:26:19.789 LeakMethod[1690:15203] got method count:45
2012-01-22 11:26:19.801 LeakMethod[1690:15203] selector name:_contentWidth (2)
2012-01-22 11:26:19.802 LeakMethod[1690:15203] selector name:_setHidesLabels: (3)
2012-01-22 11:26:19.802 LeakMethod[1690:15203] selector name:_setUsesBlackChrome: (3)
2012-01-22 11:26:19.803 LeakMethod[1690:15203] selector name:_usesBlackChrome (2)
2012-01-22 11:26:19.803 LeakMethod[1690:15203] selector name:_setHighlightsToday: (3)
2012-01-22 11:26:19.804 LeakMethod[1690:15203] selector name:setTimeInterval: (3)
2012-01-22 11:26:19.804 LeakMethod[1690:15203] selector name:dateComponents (2)
2012-01-22 11:26:19.805 LeakMethod[1690:15203] selector name:setDateComponents: (3)
2012-01-22 11:26:19.805 LeakMethod[1690:15203] selector name:setStaggerTimeIntervals: (3)
2012-01-22 11:26:19.806 LeakMethod[1690:15203] selector name:setHighlightsToday: (3)
2012-01-22 11:26:19.806 LeakMethod[1690:15203] selector name:setDate:animate: (4)
2012-01-22 11:26:19.807 LeakMethod[1690:15203] selector name:timeInterval (2)
2012-01-22 11:26:19.807 LeakMethod[1690:15203] selector name:second (2)
2012-01-22 11:26:19.807 LeakMethod[1690:15203] selector name:minute (2)
2012-01-22 11:26:19.808 LeakMethod[1690:15203] selector name:hour (2)
2012-01-22 11:26:19.808 LeakMethod[1690:15203] selector name:setDelegate: (3)
2012-01-22 11:26:19.809 LeakMethod[1690:15203] selector name:setFrame: (3)
2012-01-22 11:26:19.809 LeakMethod[1690:15203] selector name:_populateArchivedSubviews: (3)
2012-01-22 11:26:19.810 LeakMethod[1690:15203] selector name:awakeFromNib (2)
2012-01-22 11:26:19.810 LeakMethod[1690:15203] selector name:_insertPickerView (2)
2012-01-22 11:26:19.811 LeakMethod[1690:15203] selector name:_setLocale: (3)
2012-01-22 11:26:19.811 LeakMethod[1690:15203] selector name:setMinuteInterval: (3)
2012-01-22 11:26:19.811 LeakMethod[1690:15203] selector name:datePickerMode (2)
2012-01-22 11:26:19.812 LeakMethod[1690:15203] selector name:setCountDownDuration: (3)
2012-01-22 11:26:19.812 LeakMethod[1690:15203] selector name:setMinimumDate: (3)
2012-01-22 11:26:19.813 LeakMethod[1690:15203] selector name:setMaximumDate: (3)
2012-01-22 11:26:19.813 LeakMethod[1690:15203] selector name:_locale (2)
2012-01-22 11:26:19.814 LeakMethod[1690:15203] selector name:countDownDuration (2)
2012-01-22 11:26:19.814 LeakMethod[1690:15203] selector name:minimumDate (2)
2012-01-22 11:26:19.814 LeakMethod[1690:15203] selector name:maximumDate (2)
2012-01-22 11:26:19.815 LeakMethod[1690:15203] selector name:minuteInterval (2)
2012-01-22 11:26:19.815 LeakMethod[1690:15203] selector name:locale (2)
2012-01-22 11:26:19.816 LeakMethod[1690:15203] selector name:sizeThatFits: (3)
2012-01-22 11:26:19.816 LeakMethod[1690:15203] selector name:setDate:animated: (4)
2012-01-22 11:26:19.817 LeakMethod[1690:15203] selector name:setDatePickerMode: (3)
2012-01-22 11:26:19.817 LeakMethod[1690:15203] selector name:calendar (2)
2012-01-22 11:26:19.818 LeakMethod[1690:15203] selector name:timeZone (2)
2012-01-22 11:26:19.818 LeakMethod[1690:15203] selector name:setCalendar: (3)
2012-01-22 11:26:19.819 LeakMethod[1690:15203] selector name:initWithFrame: (3)
2012-01-22 11:26:19.819 LeakMethod[1690:15203] selector name:setLocale: (3)
2012-01-22 11:26:19.819 LeakMethod[1690:15203] selector name:setTimeZone: (3)
2012-01-22 11:26:19.820 LeakMethod[1690:15203] selector name:setDate: (3)
2012-01-22 11:26:19.820 LeakMethod[1690:15203] selector name:initWithCoder: (3)
2012-01-22 11:26:19.821 LeakMethod[1690:15203] selector name:encodeWithCoder: (3)
2012-01-22 11:26:19.825 LeakMethod[1690:15203] selector name:date (2)

There are many pr*vate methods.

The _setUsesBlackChrome: seems to be useful. But we don't know how to implement it.

( ̄▽ ̄) >> >> >> We can make a Kagemusha, yeah I like the movie.

@implementation NSObject (LeakMethod)

+ (void)prepareKagemusha:(Class)c methodMap:(NSDictionary*)map {

    unsigned int count = 0;
    Method *array = class_copyMethodList( c, &count);
    for(int i = 0 ; i < count ; i++){
        Method method = array[i];
        SEL methodselector = method_getName(method);
        const char* methodname = sel_getName(methodselector);
        unsigned int argcount = method_getNumberOfArguments(method);
        NSString *mn = [NSString stringWithCString:methodname encoding:NSASCIIStringEncoding];
        DLog(@"selector name:%@ (%d)", mn, argcount);
        NSString* newName = [map objectForKey:mn];
        if( newName ) {
            IMP method_imp = method_getImplementation(method);
            SEL selector = NSSelectorFromString(newName);
            if(method_imp){
                class_addMethod([UIDatePicker class], selector, method_imp, method_getTypeEncoding(method));
                break;
            }
        }        
    }    
}

@end
[NSObject prepareKagemusha:NSClassFromString(@"UIDatePicker") methodMap:[NSDictionary dictionaryWithObjectsAndKeys:@"mySetUsesBlackChrome:", @"_setUsesBlackChrome:", nil]];

Shingen sama lives again ( ^_^)/~~~ .

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home