1:RunTiem交换方法实现
//runTime交换方法实现
// 1,创建已有类的分类,并且实现自己的方法
// @implementation UIImage (image)
// +(UIImage *)ym_imageNamed:(NSString *)name
// 2,在类方法load里面用runtime获取该类原来方法和自己实现的方法
// 3,用run time交换方法实现,注意这里是方法指针的交换,需要注意的是别调错方法,发生死循环
// +(void)load
// {
// // 交换方法的实现,方法都是定义在类里
// // class_getMethodImplementation 获取方法实现
// // method_getImplementation(<#Method m#>)
// // class_getClassMethod表示获取类方法
// // class_getInstanceMethod获取一个对象方法
// // class:获取哪个类方法
// Method imageNameMethod = class_getClassMethod([UIImage class], @selector(imageNamed:));
// Method ym_imageNameMethod = class_getClassMethod([UIImage class], @selector(ym_imageNamed:));
// //交换方法实现,实际上是修改了方法指针
// method_exchangeImplementations(imageNameMethod, ym_imageNameMethod);
}
//使用方法
UIImage *image = [UIImage imageNamed:@"1232"];
2:RunTime动态添加方法
创建一Person类,给该类动态添加方法。
//ViewController.m
(1)#import "ViewController.h"
#import “Person.h"
- (void)viewDidLoad {
[super viewDidLoad];
Person *p = [[Person alloc] init];
// 动态添加无参数的方法
[p performSelector:@selector(eat)];
}
(2)Person.m文件
#import "Person.h"
#import
@implementation Person
//定义函数
//默认一个方法都有两个参数,self,_cmd,这叫隐式参数
//self:方法调用者
//_cmd:调用方法的编号
void aaaa (id self, SEL _cmd){
NSLog(@"调用了eat这个函数%@%@",self,NSStringFromSelector(_cmd));
}
// 动态添加方法,首先实现resolveInstanceMethod方法
// resolveInstanceMethod调用:调用了一个没有实现的方法时,就会调用resolveInstanceMethod
// resolveInstanceMethod作用:
// sel:没用实现方法
+ (BOOL)resolveInstanceMethod:(SEL)sel
{
NSLog(@"---->%@",NSStringFromSelector(sel));
if (sel == @selector(eat)) {
/*
class:给哪个类添加方法
SEL:添加方法的方法编号是什么
IMP:方法实现,函数入口,函数名
type:方法类型
*/
// "v@:" 查看runTime官方文档 Dynamic Method Resolution和Type Encodings
//给一个类添加方法
class_addMethod([self class], sel, (IMP)aaaa, "v@:");
//表示处理完
return YES;
}
return [super resolveInstanceMethod:sel];
}
@end
3.RunTime动态添加属性
例如:实现NSObject类别里添加属性(本质是指针间的关联)
(1)创建NSObject+objc分类,在.h文件中实现:
@interface NSObject (objc)
//@property在分类里的作用,只会实现get,set方法的声明,不会去实现。因此需要自己去实现
@property (strong, nonatomic) NSString *name;
@end
(2)在.m文件中实现:
#import "NSObject+objc.h"
#import
static char nameKey;
@implementation NSObject (objc)
- (void)setName:(NSString *)name
{
/*
添加属性,跟对象
给某个对象产生关联,添加属性
object:给哪个对象添加属性
key:属性名,根据key去获取关联的对象
value:关联的值
policy:关联的策略
void * == id
*/
objc_setAssociatedObject(self, &nameKey, name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSString *)name
{
return objc_getAssociatedObject(self, &nameKey);
}
@end
(3)ViewController类中使用方法:
NSObject *obj = [[NSObject alloc] init];
obj.name = @"1232";
NSLog(@"----->>%@",obj.name);
4.RunTime消息机制
//
// Person.h
// runTime交换方法
//
// Created by YanMacBook on 6/16/16.
// Copyright © 2016 YanMacBook. All rights reserved.
//
#import
@interface Person : NSObject
- (void)eat;
+ (void)eat;
@end
.m文件中实现方法
- (void)eat
{
NSLog(@"------对象方法------");
}
+ (void)eat
{
NSLog(@"-----类方法--------");
}
使用方法:
//runTime实例对象调用方法
// Person *p = [[Person alloc] init];
// objc_msgSend(p, @selector(eat));
//runTime类对象调用方法
Class PersonObjc = [Person class];
objc_msgSend(PersonObjc, @selector(eat));