runtime相关RuntimeiOS学习记录

Objective-C Runtime 学习笔记之Objecti

2016-06-05  本文已影响187人  我系哆啦

什么是Runtime

Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了运行时来处理。这种动态语言的优势在于:我们写代码时更具灵活性,如我们可以把消息转发给我们想要的对象,或者随意交换一个方法的实现等.
我们将C++和Objective进行对比,虽然C++和Objective-C都是在C的基础上加入面向对象的特性扩充而成的程序设计语言,但二者实现的机制差异很大。C++是基于静态类型,而Objective-C是基于动态运行时类型。也就是说用C++编写的程序编译时就直接编译成了可令机器读懂的机器语言;用Objective-C编写的程序不能直接编译成可令机器读懂的机器语言,而是在程序运行的时候,通过Runtime把程序转为可令机器读懂的机器语言。Runtime是Objective不可缺少的重要一部分。
**传送门->runtime源码

类和对象

<pre>
/// An opaque type that represents an Objective-C class.
typedef struct objc_class Class;
typedef struct objc_object id;
/// Represents an instance of a class.

struct objc_class {
Class isa OBJC_ISA_AVAILABILITY;

if !OBJC2

Class super_class                                        OBJC2_UNAVAILABLE;
const char *name                                         OBJC2_UNAVAILABLE;
long version                                             OBJC2_UNAVAILABLE;
long info                                                OBJC2_UNAVAILABLE;
long instance_size                                       OBJC2_UNAVAILABLE;
struct objc_ivar_list *ivars                             OBJC2_UNAVAILABLE;
struct objc_method_list **methodLists                    OBJC2_UNAVAILABLE;
struct objc_cache *cache                                 OBJC2_UNAVAILABLE;
struct objc_protocol_list *protocols                     OBJC2_UNAVAILABLE;

endif

} OBJC2_UNAVAILABLE;

struct objc_object {
Class isa OBJC_ISA_AVAILABILITY;
};
</pre>

成员变量和属性

<pre>
//成员变量 Ivar

ifdef LP64

int space OBJC2_UNAVAILABLE; // 占用空间

endif

}
</pre>

<pre>
typedef struct objc_property *objc_property_t;
typedef struct {
const char *name; // 名称
const char *value; // 值(通常是空的)
} objc_property_attribute_t;
</pre>

<pre>
// 获取类中指定名称实例成员变量的信息
Ivar class_getInstanceVariable ( Class cls, const char *name );
// 获取类成员变量的信息
Ivar class_getClassVariable ( Class cls, const char *name );
// 添加成员变量
BOOL class_addIvar ( Class cls, const char *name, size_t size, uint8_t alignment, const char *types );
// 获取整个成员变量列表
Ivar * class_copyIvarList ( Class cls, unsigned int *outCount );
</pre>

<pre>
// 获取指定的属性
objc_property_t class_getProperty ( Class cls, const char *name );
// 获取属性列表
objc_property_t * class_copyPropertyList ( Class cls, unsigned int *outCount );
// 为类添加属性
BOOL class_addProperty ( Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount );
// 替换类的属性
void class_replaceProperty ( Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount );
</pre>

方法(SEL,IMP,METHOD)

除了以上类型外,还有objc_protocol_list,cache,version等
上面基本介绍了runtime中类和对象的基本知识,为了加深印象,这里做一个例子,手动创建一个类,添加方法并直接调用,遍历其中的成员变量和属性

runtime实践

<pre>
/**

void test_runtime_class()
{
//动态创建一个继承自NSObject的Car类
Class Car = objc_allocateClassPair([NSObject class], "Car", 0);

//动态添加一个NSString *_name的成员变量
class_addIvar(Car, "_name", sizeof(NSString*), log2(sizeof(NSString*)), @encode(NSString*));
//动态添加一个int _num成员变量
class_addIvar(Car, "_num", sizeof(int), sizeof(int), @encode(int));

//注册方法名为sayHello的方法名
SEL sel = sel_registerName("sayHello:");
//动态添加sayHello的方法
class_addMethod(Car, sel, (IMP)sayHelloFunction, "v@:@");

//注册Car类
objc_registerClassPair(Car);

//创建Car的实例对象
id carInstance = [[Car alloc] init];

//从类中获取成员变量,并为成员变量赋值
Ivar nameIvar = class_getInstanceVariable(Car, "_name");
object_setIvar(carInstance, nameIvar, @"法拉利🚗");
Ivar numIvar = class_getInstanceVariable(Car, "_num");
object_setIvar(carInstance, numIvar, @4);

//直接调用方法
((void (*)(id,SEL,id)) objc_msgSend)(carInstance,sel,@"跑起来了");

//销毁类
objc_disposeClassPair(Car);

}
</pre>
<pre>
//
// People.m
// runtimeDemo
//
// Created by aaron on 16/6/5.
// Copyright © 2016年 aaron. All rights reserved.
// 遍历获取类对象的成员变量和属性列表

import "People.h"

import <objc/runtime.h>

@implementation People

@end
</pre>

上一篇 下一篇

猜你喜欢

热点阅读