Runtimeの件は

4082 ワード

前言

// 
#include

テストを容易にするために、テストクラスを定義しました.
//.h
#import 

@interface TestClass : NSObject

- (void)fun1;

@end
//.m
#import "TestClass.h"

@implementation TestClass

-(void)fun1
{
    NSLog(@"I am TestClass fun1...");
}

@end


1.オブジェクトコピー:id object_copy(id obj, size_t size)

- (void) copyObj
{
    TestClass *obj = [TestClass new];
    NSLog(@"%p", &obj);
    
    id objTest = object_copy(obj,sizeof(obj));
    NSLog(@"%p", &objTest);

    [objTest fun1];
}

 :
2013-07-26 15:35:11.547 HighOC[6859:c07] 0xbfffdf64
2013-07-26 15:35:11.547 HighOC[6859:c07] 0xbfffdf60
2013-07-26 15:35:11.547 HighOC[6859:c07] fun1

説明:object_copy関数はオブジェクトのコピーを実現します.

2.オブジェクト解放id object_dispose(id obj)

- (void) objectDispose
{
    TestClass *obj = [TestClass new];
    object_dispose(obj);
    
    [obj release];
    [obj fun1];
}
 : crash
malloc: *** error for object 0x758e6d0: pointer being freed was not allocated

3.オブジェクトのクラスの変更/オブジェクトのクラスの取得


Class object_setClass(id obj, Class cls) Class object_getClass(id obj)
- (void) setClassTest
{
    TestClass *obj = [TestClass new];
    [obj fun1];
    
    Class aClass =object_setClass(obj, [Other Class]);
    //obj      swap the isa to an isa
    NSLog(@"aClass:%@",NSStringFromClass(aClass));
    NSLog(@"obj class:%@",NSStringFromClass([objclass]));
    [obj fun2];
}
- (void) getClassTest
{
    TestClass *obj = [TestClass new];
    Class aLogClass =object_getClass(obj);
    NSLog(@"%@",NSStringFromClass(aLogClass));
}


4.オブジェクトのクラス名constchar*object_を取得getClassName(id obj)

- (void) getClassName
{
    TestClass *obj = [TestClass new];
    NSString *className = [NSStringstringWithCString:object_getClassName(obj)encoding:NSUTF8StringEncoding];
    NSLog(@"className:%@", className);
    }

5.クラスへのメソッドの追加


BOOL class_addMethod(Class cls,SEL name,IMP imp, const char *types)

パラメータ

- (void) oneParam {
    
    TestClass *instance = [[TestClass alloc]init];
    //     
    class_addMethod([TestClass class],@selector(ocMethod:), (IMP)cfunction,"i@:@");
    
    if ([instance respondsToSelector:@selector(ocMethod:)]) {
        NSLog(@"Yes, instance respondsToSelector:@selector(ocMethod:)");
        objc_msgSend(instance,@selector(ocMethod:),@" ");
    } else
    {
        NSLog(@"Sorry");
    }
}

/**  OCMethod */
int cfunction(id self, SEL _cmd, NSString *str) {
    NSLog(@"%@", str);
    return10;// 
}

2つのパラメータ

- (void) twoParam {
    
      TestClass *instance = [[TestClass alloc]init];
    //     
    class_addMethod([TestClass class],@selector(ocMethod:), (IMP)cfunction,"i@:@");
    
    if ([instance respondsToSelector:@selector(ocMethod:)]) {
        NSLog(@"Yes, instance respondsToSelector:@selector(ocMethod:)");
        objc_msgSend(instance,@selector(ocMethod:),@" ",@" ....");
    } else
    {
        NSLog(@"Sorry");
    }
}

/**  OCMethod */
int cfunctionA(id self, SEL _cmd, NSString *str, NSString *str1) {
    NSLog(@"%@-%@", str, str1);
    return20;// 
}


説明:BOOL class_addMethod(Class cls,SEL name,IMP imp,const char*types)という関数の変数の意味は.Classはメソッドを追加するターゲットクラスの名前SEL nameとして理解することができ、追加するメソッド名IMP impという実装可能なメソッド名として理解することができ、少なくとも2つのパラメータ、それぞれid self,SEL_を含む必要がある.cmd Const char*typesはパラメータの属性として理解できる.ここでtypesパラメータは「i@:@」であり、順番にそれぞれ次のように表される.
i      int, v void

@      id(self)

:     SEL(_cmd)

@     id(str)

参考お礼:http://blog.csdn.net/lvmaker/article/details/32396167 https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ObjCRuntimeRef/index.html#//apple_ref/c/func/method_setImplementation