Runtime消息机制,交换方法,动态添加方法,分类添加属性
2016-06-13 11:04
549 查看
Runtime 简称运行时,OC就是运行时机制
// OC:运行时机制,消息机制是运行时机制最重要的机制
//
消息机制:任何方法调用,本质都是发送消息
严格检查运行机制设置为no
调用类方法,本质也会将类转化为对象调用其方法
Person *p = [[Person
alloc] init];
//
让p发送消息
objc_msgSend(p,
@selector(eat));
objc_msgSend(p,
@selector(run:),10);
//
获取类对象
Class personClass = [Person
class];
// [personClass performSelector:@selector(eat)];
//
运行时
objc_msgSend(personClass,
@selector(eat));
Runtime 交换方法(用系统的方法调用,不用每个文件引入分类头文件)
分类里面不能调用父类方法,只能用运行时
交换方法实现,方法都是定义在类里面
加载类方法中调用(load)
+ (void)load
{
//
交换方法实现,方法都是定义在类里面
// class_getMethodImplementation:获取类方法实现
// class_getInstanceMethod:获取对象方法
// class_getClassMethod:获取类方法
// IMP:方法实现
// imageNamed
// Class:获取哪个类方法
// SEL:获取方法编号,根据SEL就能去对应的类找方法
Method imageNameMethod = class_getClassMethod([UIImage
class],
@selector(imageNamed:));
// xmg_imageNamed
Method xmg_imageNamedMethod = class_getClassMethod([UIImage
class],
@selector(xmg_imageNamed:));
//
交换方法实现
method_exchangeImplementations(imageNameMethod, xmg_imageNamedMethod);
}
+ (UIImage
*)xmg_imageNamed:(NSString
*)imageName
{
// 1.加载图片
UIImage *image = [UIImage
xmg_imageNamed:imageName];
// 2.判断功能
if (image ==
nil) {
NSLog(@"加载image为空");
}
return image;
}
Runtime 动态添加方法
有没有使用performSelector,有没有动态添加过方法
// performSelector:动态添加方法 (运行时才会报错)
//
动态添加方法,首先实现这个resolveInstanceMethod
// resolveInstanceMethod调用:当调用了没有实现的方法没有实现就会调用resolveInstanceMethod
// resolveInstanceMethod作用:就知道哪些方法没有实现,从而动态添加方法
// sel:没有实现方法
Person *p = [[Person
alloc] init];
#import
"Person.h"
//
动态添加方法
// [p performSelector:@selector(eat)];
[p performSelector:@selector(eat:) withObject:@111];
//
定义函数
//
没有返回值,参数(id,SEL)
// void(id,SEL)
void
aaaa(id
self,
SEL
_cmd,
id
param1)
{
NSLog(@"调用eat
%@ %@ %@",self,NSStringFromSelector(_cmd),param1);
}
//
默认一个方法都有两个参数,self,_cmd,隐式参数
// self:方法调用者
// _cmd:调用方法的编号
//
动态添加方法,首先实现这个resolveInstanceMethod
// resolveInstanceMethod调用:当调用了没有实现的方法没有实现就会调用resolveInstanceMethod
// resolveInstanceMethod作用:就知道哪些方法没有实现,从而动态添加方法
// sel:没有实现方法
+ (BOOL)resolveInstanceMethod:(SEL)sel
{
// NSLog(@"%@",NSStringFromSelector(sel));
//
动态添加eat方法
// if ([NSStringFromSelector(sel) isEqualToString:@"eat"]) {
//}
if (sel ==
@selector(eat:)) {
/*
cls:给哪个类添加方法
SEL:添加方法的方法编号是什么
IMP:方法实现,函数入口,函数名
types:方法类型
*/
// @:对象
:SEL
class_addMethod(self, sel, (IMP)aaaa,
"v@:@");
//
处理完
return
YES;
}
return [super
resolveInstanceMethod:sel];
}
Runtime 分类添加属性
例:给NSObject添加name属性
NSObject
*objc = [[NSObject
alloc] init];
objc.name
=
@"123";
NSLog(@"%@",objc.name);
@interface
NSObject (Objc)
@property
(nonatomic,
strong)
NSString
*name;
@end
#import
"NSObject+Objc.h"
#import
<objc/message.h>
@implementation
NSObject (Objc)
//static NSString *_name;
- (void)setName:(NSString
*)name
{
//
添加属性,跟对象
//
给某个对象产生关联,添加属性
// object:给哪个对象添加属性
// key:属性名,根据key去获取关联的对象
,void * == id
// value:关联的值
// policy:策越
objc_setAssociatedObject(self,
@"name", name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
// _name = name;
}
- (NSString
*)name
{
return objc_getAssociatedObject(self,
@"name");
}
@end
// OC:运行时机制,消息机制是运行时机制最重要的机制
//
消息机制:任何方法调用,本质都是发送消息
严格检查运行机制设置为no
调用类方法,本质也会将类转化为对象调用其方法
Person *p = [[Person
alloc] init];
//
让p发送消息
objc_msgSend(p,
@selector(eat));
objc_msgSend(p,
@selector(run:),10);
//
获取类对象
Class personClass = [Person
class];
// [personClass performSelector:@selector(eat)];
//
运行时
objc_msgSend(personClass,
@selector(eat));
Runtime 交换方法(用系统的方法调用,不用每个文件引入分类头文件)
分类里面不能调用父类方法,只能用运行时
交换方法实现,方法都是定义在类里面
加载类方法中调用(load)
+ (void)load
{
//
交换方法实现,方法都是定义在类里面
// class_getMethodImplementation:获取类方法实现
// class_getInstanceMethod:获取对象方法
// class_getClassMethod:获取类方法
// IMP:方法实现
// imageNamed
// Class:获取哪个类方法
// SEL:获取方法编号,根据SEL就能去对应的类找方法
Method imageNameMethod = class_getClassMethod([UIImage
class],
@selector(imageNamed:));
// xmg_imageNamed
Method xmg_imageNamedMethod = class_getClassMethod([UIImage
class],
@selector(xmg_imageNamed:));
//
交换方法实现
method_exchangeImplementations(imageNameMethod, xmg_imageNamedMethod);
}
+ (UIImage
*)xmg_imageNamed:(NSString
*)imageName
{
// 1.加载图片
UIImage *image = [UIImage
xmg_imageNamed:imageName];
// 2.判断功能
if (image ==
nil) {
NSLog(@"加载image为空");
}
return image;
}
Runtime 动态添加方法
有没有使用performSelector,有没有动态添加过方法
// performSelector:动态添加方法 (运行时才会报错)
//
动态添加方法,首先实现这个resolveInstanceMethod
// resolveInstanceMethod调用:当调用了没有实现的方法没有实现就会调用resolveInstanceMethod
// resolveInstanceMethod作用:就知道哪些方法没有实现,从而动态添加方法
// sel:没有实现方法
Person *p = [[Person
alloc] init];
#import
"Person.h"
//
动态添加方法
// [p performSelector:@selector(eat)];
[p performSelector:@selector(eat:) withObject:@111];
//
定义函数
//
没有返回值,参数(id,SEL)
// void(id,SEL)
void
aaaa(id
self,
SEL
_cmd,
id
param1)
{
NSLog(@"调用eat
%@ %@ %@",self,NSStringFromSelector(_cmd),param1);
}
//
默认一个方法都有两个参数,self,_cmd,隐式参数
// self:方法调用者
// _cmd:调用方法的编号
//
动态添加方法,首先实现这个resolveInstanceMethod
// resolveInstanceMethod调用:当调用了没有实现的方法没有实现就会调用resolveInstanceMethod
// resolveInstanceMethod作用:就知道哪些方法没有实现,从而动态添加方法
// sel:没有实现方法
+ (BOOL)resolveInstanceMethod:(SEL)sel
{
// NSLog(@"%@",NSStringFromSelector(sel));
//
动态添加eat方法
// if ([NSStringFromSelector(sel) isEqualToString:@"eat"]) {
//}
if (sel ==
@selector(eat:)) {
/*
cls:给哪个类添加方法
SEL:添加方法的方法编号是什么
IMP:方法实现,函数入口,函数名
types:方法类型
*/
// @:对象
:SEL
class_addMethod(self, sel, (IMP)aaaa,
"v@:@");
//
处理完
return
YES;
}
return [super
resolveInstanceMethod:sel];
}
Runtime 分类添加属性
例:给NSObject添加name属性
NSObject
*objc = [[NSObject
alloc] init];
objc.name
=
@"123";
NSLog(@"%@",objc.name);
@interface
NSObject (Objc)
@property
(nonatomic,
strong)
NSString
*name;
@end
#import
"NSObject+Objc.h"
#import
<objc/message.h>
@implementation
NSObject (Objc)
//static NSString *_name;
- (void)setName:(NSString
*)name
{
//
添加属性,跟对象
//
给某个对象产生关联,添加属性
// object:给哪个对象添加属性
// key:属性名,根据key去获取关联的对象
,void * == id
// value:关联的值
// policy:策越
objc_setAssociatedObject(self,
@"name", name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
// _name = name;
}
- (NSString
*)name
{
return objc_getAssociatedObject(self,
@"name");
}
@end
相关文章推荐
- Java Runtime Environment 5.0 Update 12 下载
- php set_magic_quotes_runtime() 函数过时解决方法
- Asp.Net 程序错误Runtime Error原因与解决
- System 类 和 Runtime 类的常用用法介绍
- NET Runtime Optimization Service 1101 错误的解决方法
- 自动释放池的前世今生 ---- 深入解析 autoreleasepool
- 上古时代 Objective-C 中哈希表的实现
- 懒惰的 initialize 方法
- 深入解析 ObjC 中方法的结构
- 你真的了解 load 方法么?
- 从源代码看 ObjC 中消息的发送
- IOS高级教程2:反射根据变量的引用获取变量名
- iOS学习之Objective-C 2.0 运行时系统编程
- iOS runtime原理
- runtime 运行时机制 完全解读
- runtime实际应用
- Objective-C 的动态提示和技巧
- Objective-C Associated Objects 的实现原理
- (1)知识准备【利用objective-c的runtime特性,结合FMDB实现一个轻量级的ORM】
- (2)预期+思考【利用objective-c的runtime特性,结合FMDB实现轻量级的ORM】