Runtime梳理(四)

挖就挖底层.png

继上Runtime梳理(三)
前面讲Runtime其实都是基于理论的,文绉绉的,湿哒哒的感觉并没有什么软用;那么这一篇我们就轻松一点复习加一点Runtime图解,是的Runtime更加通俗易懂,方便理解,架构知识吧,回顾一下前面Runtime知识:

概念类

  1. id和Class

Class super_class const char *name long version long info long instance_size objec_ivar_list *ivars objc_method_list **methodLists objc_cache_list *cache objc_protocol_list *protocols

  1. SEL
    objc_selector *SELobjc_selector char *name char *type

  2. Method

id (* IMP)(id,SEL,...);

  1. IMP
    objc_method *Method objc_method SEL method_name obcj_method char *method_types IMP method_imp

  2. Ivar

objc_ivar *Ivar objc_ivar char *ivar_name objc_ivar char *ivar_type objc_ivar int ivar_offset objc_ivar int space objc_propery_t objc_property_t是属性 objc_property *objc_property_t objc_property_attribute_t const char*name const char*value

  1. Cache
    objc_cache *Cache objc_cache unsigned int mask unsigned int occupied Method buckets[1]

  2. Category

objc_catagory *Category char *category char *class_name objc_method_list *instance_methods objc_method_list *class_methods objc_method_list *protocols

方法

  1. 消息传递
    objc_msgSend objc_msgSend_stret: objc_msgSendSuper: objc_msgSendSuper_stret:

  2. 消息动态解析

resolveInstanceMethod: forwardingTargetForSelector: methodSignatureForSelector: forwardInvocation: doesNotRecognizeSelector

  1. 补充方法和函数
    // 手动添加一个类、属性、变量、方法、释放内存、赋值、方法调用 object_getIvar(self, class_getInstanceVariable([self class], "_age")); objc_registerClassPair(People); objc_allocateClassPair([NSObject class], "Person", 0); class_addIvar(People, "_name", sizeof(NSString*), log2(sizeof(NSString *)); @encode(NSString *)); SEL s = sel_registerName("say:"); class_addMethod(People, s, (IMP)sayFunction, "good"); Ivar ageIvar = class_getInstanceVariable(People, "_age"); object_setIvar(peopleInstance, ageIvar, @18); ((void (*)(id, SEL, id))objc_msgSend)(peopleInstance, s, @"大家好"); objc_disposeClassPair(People);

class_copyPropertyList([self class], &count);
property_getName(properties[i]);
//
free();
//
class_copyIvarList([self class], &count);
ivar_getName(ivars[i]);
//
class_copyMethodList([self class], &count);
SEL methodSEL = method_getName(methods[i]);
sel_getName(methodSEL);
int arguments = method_getNumberOfArguments(methods[i]);
// 关联对象 objc_association_retain_nonatomc
objc_setAssociatedObject(self, @selector(associatedBust), bust, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
// 获取关联
objc_getAssociatedObject(self, @selector(associatedBust));
// propertySetterByKey:自定义方法
SEL setter = [self propertySetterByKey:key];
((void()(id, SEL, id))objc_msgSend)(self, setter, value);
//
((void(
)(id, SEL))objc_msgSend)((id)car, @selector(eat));
// 交换两个方法地址
method_exchangeImplementations(imageWihtName, imageName);


####发现
+ Runtime提供一组函数,函数的形式主要为`class_copyXXXX`。这组函数就是用来获取`Ivar、Method、Property、Protocol`的,他们分别是:
`class_copyIvarList
class_copyPropertyList
class_copyProtocolList
class_copyMethodList`
set get ...亦有规律可循

+ 我们用一张图来看一下相关的API吧:
![Runtime.png](http://upload-images.jianshu.io/upload_images/1095409-0d115a91ca536741.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

+ 我们来装个逼吧,提取手机所有已经安装过的App列表,包含Bundle ID!它就是通过Runtime去获取workspace类,然后performSelector函数,这是很装逼特技:
> ````
Class LSApplicationWorkspace_class = objc_getClass("LSApplicationWorkspace");
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
NSObject *workspace = [LSApplicationWorkspace_class performSelector:@selector(defaultWorkspace)];
NSLog(@"Installed apps:%@",[workspace performSelector:@selector(allApplications)]);
#pragma clang diagnostic pop
  • 通过Class获取链接库名称
Class LSApplicationWorkspace_class = objc_getClass("LSApplicationWorkspace");
const char *name = class_getImageName(LSApplicationWorkspace_class);
printf("%s\n",name);
  • 补充一个Runtime的协议运用
    创建一个RuntimeProtocol类
// RuntimeProtocol.h
#import <Foundation/Foundation.h>
@protocol RuntimeBaseProtocol <NSObject>
@optional
- (void)doBaseAction;
@end
@protocol RuntimeProtocol <NSObject>
@required
- (void)doRequiredAction;
@optional
- (void)doOptionalAction;
@end
@interface RuntimeProtocol : NSObject <RuntimeProtocol,RuntimeBaseProtocol>
{
    NSString * name;
    NSString * kind;
}
@property (copy, nonatomic) NSString * value;
@property (assign, nonatomic) int age;
+ (void)doClassMethod;
// RuntimeProtocol.m 没有东西
#import "RuntimeProtocol.h"
@implementation RuntimeProtocol
@end

打印协议名称:

unsigned int count = 0;
    __unsafe_unretained Protocol ** protocols = class_copyProtocolList([RuntimeProtocol class], &count);
    for (NSUInteger i = 0; i < count; i++)
    {
        const char * name = protocol_getName(protocols[i]);
        printf("%s\n",name);
    }````

结果:
`
RuntimeProtocol
RuntimeBaseProtocol
`

打印属性:
> 

unsigned int countP = 0;
objc_property_t * properties = class_copyPropertyList([RuntimeProtocol class], &countP);
for (unsigned int i = 0; i < countP; i++)
{
const char * name = property_getName(properties[i]);
printf("%s\n",name);
}


结果是这样的:
`
value
age
hash   ???
superclass ???
description ???
debugDescription ???
`

发现了一点不一样的东西:`hash、superclass、description、debugDescription` 其实他们是从NSObject来的,可以自己查找资料看看


###用完整的表述一下:
![Runtime2.png](http://upload-images.jianshu.io/upload_images/1095409-c85b1ef10e7abaf4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

下一篇继续: [《[RuntimeAPI》](http://www.jianshu.com/p/510ec5f75ea7)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容

  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,678评论 0 9
  • 我们常常会听说 Objective-C 是一门动态语言,那么这个「动态」表现在哪呢?我想最主要的表现就是 Obje...
    Ethan_Struggle阅读 2,170评论 0 7
  • 本文详细整理了 Cocoa 的 Runtime 系统的知识,它使得 Objective-C 如虎添翼,具备了灵活的...
    lylaut阅读 791评论 0 4
  • 转载:http://yulingtianxia.com/blog/2014/11/05/objective-c-r...
    F麦子阅读 726评论 0 2
  • 本文转载自:http://yulingtianxia.com/blog/2014/11/05/objective-...
    ant_flex阅读 744评论 0 1