Rover12421's Blog

The End.

Objective-C运行时动态添加一个类

TestClass.h
//
//  TestClass.h
//
//  Created by Rover12421 on 07/31/13.
//
//
#import
@interface TestClass : NSObject
- (void) test;
+ (void) test2;
@end

TestClass.m

//
//  TestClass.m
//
//  Created by Rover12421 on 07/31/13.
//
//

#import "TestClass.h"

@implementation TestClass
- (void) test
{
   NSLog(@"Test ...................");
}

+ (void) test2
{
   NSLog(@"Test2 ...................");
}
@end

Test.xm(hook时测试)

//
//  Test.xm
//
//  Created by Rover12421 on 07/31/13.
//
//

#import "TestClass.h"
#import

#import

static void setExpressionFormula(id self, SEL cmd, id value)
{
   object_setInstanceVariable(self, "expression", value);
   NSLog(@"call setExpressionFormula %@", value);
}

static void getExpressionFormula(id self, SEL cmd)
{
   void *value = NULL;
   object_getInstanceVariable(self, "expression", &value);
   NSLog(@"call getExpressionFormula %@", value);
}

static Class getTestClassEx()
{
   const char * className = "TestClassEx";
   Class kclass = objc_getClass(className);
   if (!kclass)
   {
       NSLog(@"add Class TestClassEx");
       Class superClass = [TestClass class];
       kclass = objc_allocateClassPair(superClass, className, );
       
       NSUInteger size;
       NSUInteger alignment;
       NSGetSizeAndAlignment("*", &size, &alignment);
       class_addIvar(kclass, "expression", size, alignment, "*");
       
       class_addMethod(kclass, @selector(setExpressionFormula:), (IMP)setExpressionFormula, "v@:@");
       class_addMethod(kclass, @selector(getExpressionFormula), (IMP)getExpressionFormula, "@@:");
       objc_registerClassPair(kclass);
   }
   else
   {
       NSLog(@"find the Class TestClassEx");
   }
   return kclass;
}

static int (*orig_UIApplicationMain)(int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName);

int new_UIApplicationMain(int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName)
{
   Class testClazzEx = getTestClassEx();
   if (testClazzEx != nil) {
       NSLog(@"getTestClassEx is ok ......");
       id instance = [[testClazzEx alloc] init];
       [instance setExpressionFormula : @"test set express"];
       [instance getExpressionFormula];
       [instance test];
       [testClazzEx test2];
       [instance autorelease];
   }
   
   return orig_UIApplicationMain(argc, argv, principalClassName, delegateClassName);
   
}

%ctor
{
   @autoreleasepool {
       MSHookFunction((void *)UIApplicationMain, (void *)new_UIApplicationMain, (void **)&orig_UIApplicationMain);
   }
}

Comments