什么是runtime?

1> runtime是一套底层的C语言API(包含很多强大实用的C语言数据类型、C语言函数)
2> 实际上,平时我们编写的OC代码,底层都是基于runtime实现的
* 也就是说,平时我们编写的OC代码,最终都是转成了底层的runtime代码(C语言代码)

runtime有啥用?

1> 能动态产生一个类、一个成员变量、一个方法
2> 能动态修改一个类、一个成员变量、一个方法
3> 能动态删除一个类、一个成员变量、一个方法

常见的函数、头文件

#import <objc/runtime.h> :           成员变量、类、方法
Ivar * class_copyIvarList :              获得某个类内部的所有成员变量
Method * class_copyMethodList :     获得某个类内部的所有方法
Method class_getInstanceMethod :   获得某个实例方法(对象方法,减号-开头)
Method class_getClassMethod :        获得某个类方法(加号+开头)
method_exchangeImplementations : 交换2个方法的具体实现

#import <objc/message.h> : 消息机制
objc_msgSend(....)

#import "HMViewController.h"
#import "HMPerson.h"
#import <objc/runtime.h>
#import <objc/message.h> @interface HMViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *iconView1;
@property (weak, nonatomic) IBOutlet UIImageView *iconView2; @property (nonatomic, strong) NSMutableArray *names;
@property (nonatomic, strong) NSArray *books; @end @implementation HMViewController - (NSMutableArray *)names
{
if (_names == nil) {
self.names = [NSMutableArray array];
}
return _names;
} - (void)viewDidLoad
{
[super viewDidLoad]; // NSDictionary *info = @{@"name" : @"jack", @"age" : @10};
//
// NSString *key = nil;
//
// NSLog(@"%@", info[key]); NSMutableDictionary *info = [NSMutableDictionary dictionary];
info[@"name"] = nil; // self.books = @[@"kiuhua", @"xxx"];
//
// NSLog(@"%@", self.books[4]); // [self addName:@"jack"];
// [self addName:@"rose"];
// [self addName:@"jim"];
//
// NSLog(@"%@", self.names[4]);
// NSLog(@"%@", [self.names objectAtIndex:4]);
} - (void)addName:(NSString *)name
{
[self.names addObject:name];
} - (void)imageSwizzle
{
// 什么是iOS Swizzle?利用运行时函数交换2个方法的实现 // BOOL iOS7 = [[UIDevice currentDevice].systemVersion floatValue] >= 7.0;
// if (iOS7) {
// self.iconView1.image = [UIImage imageNamed:@"face_os7"];
// self.iconView2.image = [UIImage imageNamed:@"vip_os7"];
// } else {
// self.iconView1.image = [UIImage imageNamed:@"face"];
// self.iconView2.image = [UIImage imageNamed:@"vip"];
// }
self.iconView1.image = [UIImage imageNamed:@"face"];
self.iconView2.image = [UIImage imageNamed:@"vip"];
} - (void)testRuntimeIvar
{
// Ivar : 成员变量
unsigned int count = ;
// 获得所有的成员变量
Ivar *ivars = class_copyIvarList([HMPerson class], &count);
for (int i = ; i<count; i++) {
// 取得i位置的成员变量
Ivar ivar = ivars[i];
const char *name = ivar_getName(ivar);
const char *type = ivar_getTypeEncoding(ivar);
NSLog(@"%d %s %s", i, name, type);
} // HMPerson *p = [[HMPerson alloc] init];
// objc_msgSend(p, @selector(setAge:), 20); // NSLog(@"%d", p.age);
}

HMPerson.h /.m(获取所有成员变量)

#import <Foundation/Foundation.h>

@interface HMPerson : NSObject <NSCoding>
@property (nonatomic, assign) int age;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) double height;
- (void)run;
@end
#import "HMPerson.h"
#import <objc/runtime.h> @implementation HMPerson
- (void)run
{
NSLog(@"run----");
} - (void)encodeWithCoder:(NSCoder *)encoder
{
unsigned int count = ;
Ivar *ivars = class_copyIvarList([HMPerson class], &count);
for (int i = ; i<count; i++) {
// 取得i位置的成员变量
Ivar ivar = ivars[i];
const char *name = ivar_getName(ivar);
NSString *key = [NSString stringWithUTF8String:name];
[encoder encodeObject:[self valueForKeyPath:key] forKey:key];
}
} @end

UIImage+Extension(交换2个方法的实现)

#import <objc/runtime.h>

@implementation UIImage (Extension)
/**
* 只要分类被装载到内存中,就会调用1次
*/
+ (void)load
{
Method otherMehtod = class_getClassMethod(self, @selector(imageWithName:));
Method originMehtod = class_getClassMethod(self, @selector(imageNamed:));
// 交换2个方法的实现
method_exchangeImplementations(otherMehtod, originMehtod);
} + (UIImage *)imageWithName:(NSString *)name
{
BOOL iOS7 = [[UIDevice currentDevice].systemVersion floatValue] >= 7.0;
UIImage *image = nil;
if (iOS7) {
NSString *newName = [name stringByAppendingString:@"_os7"];
image = [UIImage imageWithName:newName];
} if (image == nil) {
image = [UIImage imageWithName:name];
}
return image;
} @end

NSObject+Extension(交换2个方法的实现)

#import <objc/runtime.h>

@implementation NSObject(Extension)
+ (void)swizzleClassMethod:(Class)class originSelector:(SEL)originSelector otherSelector:(SEL)otherSelector
{
Method otherMehtod = class_getClassMethod(class, otherSelector);
Method originMehtod = class_getClassMethod(class, originSelector);
// 交换2个方法的实现
method_exchangeImplementations(otherMehtod, originMehtod);
} + (void)swizzleInstanceMethod:(Class)class originSelector:(SEL)originSelector otherSelector:(SEL)otherSelector
{
Method otherMehtod = class_getInstanceMethod(class, otherSelector);
Method originMehtod = class_getInstanceMethod(class, originSelector);
// 交换2个方法的实现
method_exchangeImplementations(otherMehtod, originMehtod);
}
@end @implementation NSArray(Extension)
+ (void)load
{
[self swizzleInstanceMethod:NSClassFromString(@"__NSArrayI") originSelector:@selector(objectAtIndex:) otherSelector:@selector(hm_objectAtIndex:)];
} - (id)hm_objectAtIndex:(NSUInteger)index
{
if (index < self.count) {
return [self hm_objectAtIndex:index];
} else {
return nil;
}
} @end @implementation NSMutableArray(Extension)
+ (void)load
{
[self swizzleInstanceMethod:NSClassFromString(@"__NSArrayM") originSelector:@selector(addObject:) otherSelector:@selector(hm_addObject:)];
[self swizzleInstanceMethod:NSClassFromString(@"__NSArrayM") originSelector:@selector(objectAtIndex:) otherSelector:@selector(hm_objectAtIndex:)];
} - (void)hm_addObject:(id)object
{
if (object != nil) {
[self hm_addObject:object];
}
} - (id)hm_objectAtIndex:(NSUInteger)index
{
if (index < self.count) {
return [self hm_objectAtIndex:index];
} else {
return nil;
}
}
@end

最新文章

  1. java 反序列化PHP
  2. 走进AngularJs(二) ng模板中常用指令的使用方式
  3. Linux的一些常用快捷键和基本命令
  4. Python:线程
  5. 再谈扩展方法,从string.IsNullOrEmpty()说起
  6. CCNA网络工程师学习进程(2)基本的网络设备
  7. PhoneGap: Android平台入门例子(Hello World)
  8. ESI 动态缓存技术
  9. selenium实战-自动退百度云共享群
  10. WatchKit App Submission Issues
  11. HDU 1698 Just a Hook 区间更新 lazy标记
  12. C++ 不使用virtual实现多态
  13. Flink 的Window 操作(基于flink 1.3描述)
  14. Windows下的Python安装与环境变量的配置
  15. 锋利的jQuery初学(4)
  16. nmap扫描验证多种漏洞
  17. oracle No more data to read from socket之ora-07445排查解决
  18. 单击GridView进入编辑模式
  19. CF_321_B_NetFlow
  20. echo 与 od -x 与 %!xxd 命令

热门文章

  1. BENZ Prognosis System C5 SD Be connected &amp; Panasonic Xentry-Tab
  2. 千图网爬图片(BeautifulSoup)
  3. jenkins +gitlab 自动化代码秒级上线
  4. Angular4+NodeJs+MySQL 入门-05 接口调用
  5. jar包、jdk版本、兼容性
  6. CSS3实现鼠标悬停扩展效果
  7. UML建模概述
  8. ionic2 目录
  9. Windows的任务管理器怎么显示进程的图标
  10. Java笔记之Scanner先读取一个数字,在读取一行字符串方法分析