前言
//要包含的头文件
#include<objc/runtime.h>
为了方便测试,我们定义了一个测试类
//.h
#import <Foundation/Foundation.h>
@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;//随便返回个值
}
俩个参数
- (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