iOS Objc Runtime 教程+实例Demo.docx

上传人:b****6 文档编号:8897959 上传时间:2023-05-15 格式:DOCX 页数:26 大小:36.54KB
下载 相关 举报
iOS Objc Runtime 教程+实例Demo.docx_第1页
第1页 / 共26页
iOS Objc Runtime 教程+实例Demo.docx_第2页
第2页 / 共26页
iOS Objc Runtime 教程+实例Demo.docx_第3页
第3页 / 共26页
iOS Objc Runtime 教程+实例Demo.docx_第4页
第4页 / 共26页
iOS Objc Runtime 教程+实例Demo.docx_第5页
第5页 / 共26页
iOS Objc Runtime 教程+实例Demo.docx_第6页
第6页 / 共26页
iOS Objc Runtime 教程+实例Demo.docx_第7页
第7页 / 共26页
iOS Objc Runtime 教程+实例Demo.docx_第8页
第8页 / 共26页
iOS Objc Runtime 教程+实例Demo.docx_第9页
第9页 / 共26页
iOS Objc Runtime 教程+实例Demo.docx_第10页
第10页 / 共26页
iOS Objc Runtime 教程+实例Demo.docx_第11页
第11页 / 共26页
iOS Objc Runtime 教程+实例Demo.docx_第12页
第12页 / 共26页
iOS Objc Runtime 教程+实例Demo.docx_第13页
第13页 / 共26页
iOS Objc Runtime 教程+实例Demo.docx_第14页
第14页 / 共26页
iOS Objc Runtime 教程+实例Demo.docx_第15页
第15页 / 共26页
iOS Objc Runtime 教程+实例Demo.docx_第16页
第16页 / 共26页
iOS Objc Runtime 教程+实例Demo.docx_第17页
第17页 / 共26页
iOS Objc Runtime 教程+实例Demo.docx_第18页
第18页 / 共26页
iOS Objc Runtime 教程+实例Demo.docx_第19页
第19页 / 共26页
iOS Objc Runtime 教程+实例Demo.docx_第20页
第20页 / 共26页
亲,该文档总共26页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

iOS Objc Runtime 教程+实例Demo.docx

《iOS Objc Runtime 教程+实例Demo.docx》由会员分享,可在线阅读,更多相关《iOS Objc Runtime 教程+实例Demo.docx(26页珍藏版)》请在冰点文库上搜索。

iOS Objc Runtime 教程+实例Demo.docx

iOSObjcRuntime教程+实例Demo

iOSObjcRuntime教程+实例Demo

应用场景

将某些OC代码转为运行时代码,探究底层,比如block的实现原理

拦截系统自带的方法调用(Swizzle黑魔法),比如拦截imageNamed:

、viewDidLoad、alloc

实现分类也可以增加属性

实现NSCoding的自动归档和自动解档

实现字典和模型的自动转换。

(MJExtension)

修BUG神器,如果大型框架的BUG通过Runtime来解决,非常好用。

一些常用类型

Method

Method

Anopaquetypethatrepresentsamethodinaclassdefinition.

Declaration

typedefstructobjc_method*Method;

代表类定义中的方法的不透明类型。

Class

Class

AnopaquetypethatrepresentsanObjective-Cclass.

Declaration

typedefstructobjc_class*Class;

代表Objective-C中的类

Ivar

Anopaquetypethatrepresentsaninstancevariable.

Declaration

typedefstructobjc_ivar*Ivar;

代表实例变量

IMP

IMP

Apointertothestartofamethodimplementation.

指向方法实现的开始的内存地址的指针。

SEL

SEL

Definesanopaquetypethatrepresentsamethodselector.

Declaration

typedefstructobjc_selector*SEL;

代表方法的选择器

类与对象操作函数

runtime有很多的函数可以操作类和对象。

类相关的是class为前缀,对象相关操作是objc或object_为前缀。

类相关操作函数

name

//获取类的类名

constchar*class_getName(Classcls);

super_class和meta-class

//获取类的父类

Classclass_getSuperclass(Classcls);

//判断给定的Class是否是一个metaclass

BOOLclass_isMetaClass(Classcls);

instance_size

//获取实例大小

size_tclass_getInstanceSize(Classcls);

成员变量(ivars)及属性

//成员变量操作函数

//获取类中指定名称实例成员变量的信息

Ivarclass_getInstanceVariable(Classcls,constchar*name);

//获取类成员变量的信息

Ivarclass_getClassVariable(Classcls,constchar*name);

//添加成员变量

BOOLclass_addIvar(Classcls,constchar*name,size_tsize,uint8_talignment,constchar*types);//这个只能够向在runtime时创建的类添加成员变量

//获取整个成员变量列表

Ivar*class_copyIvarList(Classcls,unsignedint*outCount);//必须使用free()来释放这个数组

//属性操作函数

//获取类中指定名称实例成员变量的信息

Ivarclass_getInstanceVariable(Classcls,constchar*name);

//获取类成员变量的信息

Ivarclass_getClassVariable(Classcls,constchar*name);

//添加成员变量

BOOLclass_addIvar(Classcls,constchar*name,size_tsize,uint8_talignment,constchar*types);

//获取整个成员变量列表

Ivar*class_copyIvarList(Classcls,unsignedint*outCount);

methodLists

//添加方法

BOOLclass_addMethod(Classcls,SELname,IMPimp,constchar*types);//和成员变量不同的是可以为类动态添加方法。

如果有同名会返回NO,修改的话需要使用method_setImplementation

//获取实例方法

Methodclass_getInstanceMethod(Classcls,SELname);

//获取类方法

Methodclass_getClassMethod(Classcls,SELname);

//获取所有方法的数组

Method*class_copyMethodList(Classcls,unsignedint*outCount);

//替代方法的实现

IMPclass_replaceMethod(Classcls,SELname,IMPimp,constchar*types);

//返回方法的具体实现

IMPclass_getMethodImplementation(Classcls,SELname);

IMPclass_getMethodImplementation_stret(Classcls,SELname);

//类实例是否响应指定的selector

BOOLclass_respondsToSelector(Classcls,SELsel);

objc_protocol_list

//添加协议

BOOLclass_addProtocol(Classcls,Protocol*protocol);

//返回类是否实现指定的协议

BOOLclass_conformsToProtocol(Classcls,Protocol*protocol);

//返回类实现的协议列表

Protocol*class_copyProtocolList(Classcls,unsignedint*outCount);

version

//获取版本号

intclass_getVersion(Classcls);

//设置版本号

voidclass_setVersion(Classcls,intversion);

实例

//-----------------------------------------------------------

//MyClass.h

@interfaceMyClass:

NSObject

@property(nonatomic,strong)NSArray*array;

@property(nonatomic,copy)NSString*string;

-(void)method1;

-(void)method2;

+(void)classMethod1;

@end

//-----------------------------------------------------------

//MyClass.m

#import"MyClass.h"

@interfaceMyClass(){

NSInteger_instance1;

NSString*_instance2;

}

@property(nonatomic,assign)NSUIntegerinteger;

-(void)method3WithArg1:

(NSInteger)arg1arg2:

(NSString*)arg2;

@end

@implementationMyClass

+(void)classMethod1{

}

-(void)method1{

NSLog(@"callmethodmethod1");

}

-(void)method2{

}

-(void)method3WithArg1:

(NSInteger)arg1arg2:

(NSString*)arg2{

NSLog(@"arg1:

%ld,arg2:

%@",arg1,arg2);

}

@end

//-----------------------------------------------------------

//main.h

#import"MyClass.h"

#import"MySubClass.h"

#import

intmain(intargc,constchar*argv[]){

@autoreleasepool{

MyClass*myClass=[[MyClassalloc]init];

unsignedintoutCount=0;

Classcls=myClass.class;

//类名

NSLog(@"classname:

%s",class_getName(cls));

NSLog(@"==========================================================");

//父类

NSLog(@"superclassname:

%s",class_getName(class_getSuperclass(cls)));

NSLog(@"==========================================================");

//是否是元类

NSLog(@"MyClassis%@ameta-class",(class_isMetaClass(cls)?

@"":

@"not"));

NSLog(@"==========================================================");

Classmeta_class=objc_getMetaClass(class_getName(cls));

NSLog(@"%s'smeta-classis%s",class_getName(cls),class_getName(meta_class));

NSLog(@"==========================================================");

//变量实例大小

NSLog(@"instancesize:

%zu",class_getInstanceSize(cls));

NSLog(@"==========================================================");

//成员变量

Ivar*ivars=class_copyIvarList(cls,&outCount);

for(inti=0;i

Ivarivar=ivars[i];

NSLog(@"instancevariable'sname:

%satindex:

%d",ivar_getName(ivar),i);

}

free(ivars);

Ivarstring=class_getInstanceVariable(cls,"_string");

if(string!

=NULL){

NSLog(@"instacevariable%s",ivar_getName(string));

}

NSLog(@"==========================================================");

//属性操作

objc_property_t*properties=class_copyPropertyList(cls,&outCount);

for(inti=0;i

objc_property_tproperty=properties[i];

NSLog(@"property'sname:

%s",property_getName(property));

}

free(properties);

objc_property_tarray=class_getProperty(cls,"array");

if(array!

=NULL){

NSLog(@"property%s",property_getName(array));

}

NSLog(@"==========================================================");

//方法操作

Method*methods=class_copyMethodList(cls,&outCount);

for(inti=0;i

Methodmethod=methods[i];

NSLog(@"method'ssignature:

%s",method_getName(method));

}

free(methods);

Methodmethod1=class_getInstanceMethod(cls,@selector(method1));

if(method1!

=NULL){

NSLog(@"method%s",method_getName(method1));

}

MethodclassMethod=class_getClassMethod(cls,@selector(classMethod1));

if(classMethod!

=NULL){

NSLog(@"classmethod:

%s",method_getName(classMethod));

}

NSLog(@"MyClassis%@responsdtoselector:

method3WithArg1:

arg2:

",class_respondsToSelector(cls,@selector(method3WithArg1:

arg2:

))?

@"":

@"not");

IMPimp=class_getMethodImplementation(cls,@selector(method1));

imp();

NSLog(@"==========================================================");

//协议

Protocol*__unsafe_unretained*protocols=class_copyProtocolList(cls,&outCount);

Protocol*protocol;

for(inti=0;i

protocol=protocols[i];

NSLog(@"protocolname:

%s",protocol_getName(protocol));

}

NSLog(@"MyClassis%@responsedtoprotocol%s",class_conformsToProtocol(cls,protocol)?

@"":

@"not",protocol_getName(protocol));

NSLog(@"==========================================================");

}

return0;

}

动态创建类和对象

动态创建类

//创建一个新类和元类

Classobjc_allocateClassPair(Classsuperclass,constchar*name,size_textraBytes);//如果创建的是rootclass,则superclass为Nil。

extraBytes通常为0

//销毁一个类及其相关联的类

voidobjc_disposeClassPair(Classcls);//在运行中还存在或存在子类实例,就不能够调用这个。

//在应用中注册由objc_allocateClassPair创建的类

voidobjc_registerClassPair(Classcls);//创建了新类后,然后使用class_addMethod,class_addIvar函数为新类添加方法,实例变量和属性后再调用这个来注册类,再之后就能够用了。

使用实例

Classcls=objc_allocateClassPair(MyClass.class,"MySubClass",0);

class_addMethod(cls,@selector(submethod1),(IMP)imp_submethod1,"v@:

");

class_replaceMethod(cls,@selector(method1),(IMP)imp_submethod1,"v@:

");

class_addIvar(cls,"_ivar1",sizeof(NSString*),log(sizeof(NSString*)),"i");

objc_property_attribute_ttype={"T","@\"NSString\""};

objc_property_attribute_townership={"C",""};

objc_property_attribute_tbackingivar={"V","_ivar1"};

objc_property_attribute_tattrs[]={type,ownership,backingivar};

class_addProperty(cls,"property2",attrs,3);

objc_registerClassPair(cls);

idinstance=[[clsalloc]init];

[instanceperformSelector:

@selector(submethod1)];

[instanceperformSelector:

@selector(method1)];

动态创建对象

//创建类实例

idclass_createInstance(Classcls,size_textraBytes);//会在heap里给类分配内存。

这个方法和+alloc方法类似。

//在指定位置创建类实例

idobjc_constructInstance(Classcls,void*bytes);

//销毁类实例

void*objc_destructInstance(idobj);//不会释放移除任何相关引用

测试下效果

//可以看出class_createInstance和alloc的不同

idtheObject=class_createInstance(NSString.class,sizeof(unsigned));

idstr1=[theObjectinit];

NSLog(@"%@",[str1class]);

idstr2=[[NSStringalloc]initWithString:

@"test"];

NSLog(@"%@",[str2class]);

实例操作函数

这些函数是针对创建的实例对象的一系列操作函数。

整个对象操作的函数

//返回指定对象的一份拷贝

idobject_copy(idobj,size_tsize);

//释放指定对象占用的内存

idobject_dispose(idobj);

应用场景

//把a转换成占用更多空间的子类b

NSObject*a=[[NSObjectalloc]init];

idnewB=object_copy(a,class_getInstanceSize(MyClass.class));

object_setClass(newB,MyClass.class);

object_dispose(a);

对象实例变量进行操作的函数

//修改类实例的实例变量的值

Ivarobject_setInstanceVariable(idobj,constchar*name,void*value);

//获取对象实例变量的值

Ivarobject_getInstanceVariable(idobj,constchar*name,void**outValue);

//返回指向给定对象分配的任何额外字节的指针

void*object_getIndexedIvars(idobj);

//返回对象中实例变量的值

idobject_getIvar(idobj,Ivarivar);

//设置对象中实例变量的值

voidobject_setIvar(idobj,Ivarivar,idvalue);

对对象类操作

//返回给定对象的类名

constchar*object_getClassName(idobj);

//返回对象的类

Classobject_getClass(idobj);

//设置对象的类

Classobject_setClass(idobj,Classcls);

获取类定义

//获取已注册的类定义的列表

intobjc_getClassList(Class*buffer,intbufferCount);

//创建并返回一个指向所有已注册类的指针列表

Class*objc_copyClassList(unsignedint

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 语文

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2