SQL必知必会 ——– order by、where等

获取情势地址

大家每便发送音讯都会走objc_msgSend()方法,那么有没有方法规避音讯绑定直接获取形式的地址并调用方法吧?答案自然是一些。我们地方简单介绍了IMP,其实我们得以应用NSObject的

- (IMP)methodForSelector:(SEL)aSelector;

模式,通过该办法拿到IMP,然后调用该措施。不过避开音信绑定而从来调用的接纳并不普遍,然而假设你要反复巡回调用的话,直接拿到格局地址并调用不失为一个朴素操作。看下边的代码:

 void (*setter)(id,SEL,BOOL);
    setter = (void(*)(id,SEL,BOOL))[stu2 methodForSelector:@selector(learning)];
    NSDate *startDate = [NSDate date];
    for (int i = 0;i<100000;i++) {
        setter(stu2,@selector(learning),YES);
    }
    double deltaTime = [[NSDate date] timeIntervalSinceDate:startDate];
    NSLog(@"----%f",deltaTime);

    NSDate *startDate1 = [NSDate date];
    for (int i = 0;i<100000;i++) {
        [stu2 learning];
    }
    double deltaTime1 = [[NSDate date] timeIntervalSinceDate:startDate1];
    NSLog(@"----%f",deltaTime1);

您可以活动跑一下,看一下刻钟差别。你会发觉:获取格局地址直接调用更省时间,但请小心使用情形。

二、过滤数据

1.where语句SELECT
prod_name,prod_price FROM Products WHERE
prod_price=3.49

提个醒:WHERE子句的职务
在同时利用ORDER BY和WHERE子句时,应该让ORDER
BY位于WHERE其后,否则将会发出错误。例如:SELECT prod_name,prod_price FROM
Products WHERE prod_price=3.49 ORDER BY prod_name
ASC

图片 1

 

2.检查单个值:SELECT
prod_name,prod_price FROM Products WHERE prod_price < 0

3.不匹配检查:SELECT
vend_id,prod_name FROM Products WHERE vend_id <>’DLL01′

4.范围值检查:SELECT
prod_name,prod_price FROM Products WHERE prod_price BETWEEN 5 AND
10

5.空值检查: SELECT cust_name
FROM customers WHERE cust_email IS NULL

IMP

它是一个函数指针,指向方法的贯彻,在objc.h里面它的定义是如此的:

/// A pointer to the function of a method implementation. 
#if !OBJC_OLD_DISPATCH_PROTOTYPES
typedef void (*IMP)(void /* id, SEL, ... */ ); 
#else
typedef id _Nullable (*IMP)(id _Nonnull, SEL _Nonnull, ...); 
#endif

一、排序检索数据

1.排序数据SELECT prod_name
FROM Products ORDER BY prod_name(对prod_name列以字母顺序排序数据)

ORDER
BY子句的职位

在指定一条ORDER
BY子句时,应该保证它是SELECT语句中最后一条子句。如若它不是最终的子句,将会现出谬误音信。
因此非选取列举行排序
一般性,ORDER
BY子句中动用的列将是为呈现而采用的列。可是,实际上并不一定要这样,用非检索的列排序数据是一点一滴合法的。

2.按三个列排序SELECT
prod_id,prod_price,prod_name FROM Products ORDER BY
prod_price,prod_name

图片 2

根本的是理解在按四个列排序时,排序的各样完全按规定举办。换句话说,对于上述例子中的输出,仅在六个行有所相同的prod_price值时才对成品按prod_name进行排序。如若prod_price列中所有的值都是绝无仅有的,则不会按prod_name排序。

3.按列地点排序SELECT
prod_id,prod_price,prod_name FROM Products ORDER BY
2,3 那个和按多少个列排序结果是平等的,无非就是当然的列名称改成了职务序号。

图片 3

可以看来,这里的输出与地点的查询同一,不同之处在于ORDER
BY子句。SELECT清单中指定的是采取列的相对地点而不是列名。ORDER BY
2代表按SELECT清单中的第二个列prod_name进行排序。ORDER BY
2,3表示先按prod_price,再按prod_name举办排序。
这一技艺的显要利益在于无须再行输入列名。但它也有缺点。首先,不引人注目给出列名有可能造成错用列名排序。其次,在对SELECT清单进行更改时便于错误地对数码进行排序(忘记对ORDER
BY子句做相应的变更)。最终,假诺展开排序的列不在SELECT清单中,显著不可以利用这项技能。

4.指定排序方向SELECT
prod_id,prod_price,prod_name FROM Products ORDER BY
prod_price DESC

SELECT prod_id,prod_price,prod_name FROM
Products ORDER BY prod_price DESC,prod_name

图片 4

DESC关键字只行使到平素放在其面前的列名。在上例中,只对prod_price列指定DESC,对prod_name列不指定。由此,prod_price列以降序排序,而prod_name列(在每个价位内)仍旧按正统的升序排序。

告诫:在六个列上降序排序
假若想在五个列上举行降序排序,必须对每一列指定DESC关键字。
请留心,DESC是DESCENDING的缩写,这三个根本字都可以使用。与DESC相对的是ASC(或ASCENDING),在升序排序时方可指定它。但实在,ASC没有多大用处,因为升序是默认的(倘诺既不指定ASC也不点名DESC,则只要为ASC)。
提拔:区分轻重缓急写和排序依次
在对文本性数据开展排序时,A与a相同呢?a位于B从前,仍然Z之后?那个题材不是辩论问题,其答案取决于数据库的装置方法。
在字典(dictionary)排序依次中,A被视为与a相同,这是大部分数据库管理类另外默认行为。不过,许多DBMS允许数据库管理员在急需时改变这种表现(倘若您的数据库包含大量外国语字符,可能必须这样做)。
此处的关键问题是,假设实在需要变更那种排序依次,用简易的ORDER
BY子句可能做不到。你必须请求数据库管理员的提携。

id

id是一个我们日常应用的序列,可用来作为类型转换的中介者。它相仿于Java里面的Object,可以转移为任何的数据类型。它在objc.h里面是这样定义的:

/// Represents an instance of a class.
struct objc_object {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
};

/// A pointer to an instance of a class.
typedef struct objc_object *id;

它实际是一个objc _
object的结构体指针,而在后头将要提到的Class其实是个objc _
class的指针,而objc _ class是后续自objc _o
bject的,因而可以相互转换,这也是干什么id可以变换为此外任何的数据类型的原委。

三、高级数据过滤

1.AND操作符SELECT
prod_id,prod_price,prod_name FROM Products WHERE
vend_id=’DLL01′ AND prod_price <=4

此SQL语句检索由供应商DLL01创立且价格低于等于4新币的享有成品的称谓和价格。这条SELECT语句中的WHERE子句包含五个尺码,用AND关键字联结在同步。AND提醒DBMS只回去满意所有给定条件的行。假若某个产品由供应商DLL01创建,但价格高于4卢比,则不检索它。

AND
用在WHERE子句中的关键字,用来指示检索满足所有给定条件的行。
这些事例只包含一个AND子句,由此最多有六个过滤条件。可以扩充五个过滤条件,每个条件间都要使用AND关键字。
说明:没有ORDER BY子句
为了省去空间,也为了收缩你的输入,我在众多例子里大概了ORDER
BY子句。因而,你的输出完全有可能与书上的输出不平等。尽管重临行的多少连续对的,但它们的依次可能不同。当然,倘使你愿意也足以添加一个ORDER
BY子句,它应该置身WHERE子句之后。
2.OR操作符SELECT
vend_id,prod_price,prod_name FROM Products WHERE
vend_id=’DLL01′ OR
vend_id=’BRS01′

此SQL语句检索由任一个点名供应商成立的装有成品的产品名和价格。OR操作符告诉DBMS匹配任一条件而不是同时匹配几个标准。 

图片 5

3.求值梯次(AND
OR)

输入:

SELECT
prod_name, prod_price FROM Products 

WHERE
vend_id = ‘DLL01’ OR vend_id = ‘BRS01’ AND prod_price >=
10

输出:

图片 6

题目:请看下面的结果。重返的行中有**4行价格低于10**港币,分明,重临的行未按预想的拓展过滤。为啥会这样呢?由来在于求值的各样。SQL(像多数言语一样)在处理OR操作符前,优先处理AND操作符。当SQL看到上述WHERE子句时,它通晓为:由供应商BRS01创设的标价为10日币以上的具备产品,以及由供应商DLL01创制的持有成品,而不管其价格怎么着。换句话说,由于AND在求值过程中先期级更高,操作符被张冠李戴地组成了。

解决方法:

SELECT prod_name, prod_price FROM Products 

WHERE (vend_id =
‘DLL01’ OR vend_id = ‘BRS01’) AND
prod_price >= 10

实则只要用括号括起来就好了

唤醒:在WHERE子句中运用圆括号
其它时候利用具有AND和OR操作符的WHERE子句,都应有使用圆括号明确地分组操作符。不要过分看重默认求值顺序,即便它的确如你指望的这样。使用圆括号没有什么样坏处,它能免去歧义。

4.IN操作符

输入:

SELECT
vend_id,prod_name,prod_price FROM Products
WHERE
vend_id IN (‘DLL01′,’BRS01’)
ORDER
BY prod_name

输出:

图片 7

干什么要选取IN操作符?其亮点为:

  • 在有无数法定选项时,IN操作符的语法更明了,更直观。
  • 在与任何AND和OR操作符组合使用IN时,求值顺序更易于管理。
  • IN操作符一般比一组OR操作符执行得更快(在地点那些合法选项很少的事例中,你看不出性能差距)。
  • IN的最大亮点是足以分包其他SELECT语句,可以更动态地创制WHERE子句。第11课会对此展开详尽介绍。

IN
WHERE子句中用来指定要匹配值的清单的重中之重字,效能与OR非常。

5.NOT操作符

SELECT
prod_name FROM Products
WHERE NOT
vend_id = ‘DLL01’
ORDER
BY prod_name;

为何使用NOT?对于这里的这种简易的WHERE子句,使用NOT确实并未什么样优势。但在更复杂的子句中,NOT是可怜有效的。例如,在与IN操作符联合使用时,NOT可以非凡简单地找出与规则列表不匹配的行。

作者:今孝
出处:http://www.cnblogs.com/jinxiao-pu/p/6814043.html
本文版权归作者和乐乎共有,欢迎转载,但未经作者同意必须保留此段声明,且在作品页面显著地方给出原文连接。

认为好就点个推荐把!

Runtime

Method

主意,它实际是一个objc_method的结构体指针,其定义如下:

/// An opaque type that represents a method in a class definition.
typedef struct objc_method *Method;

struct objc_method {
    SEL _Nonnull method_name                                 OBJC2_UNAVAILABLE;
    char * _Nullable method_types                            OBJC2_UNAVAILABLE;
    IMP _Nonnull method_imp                                  OBJC2_UNAVAILABLE;
}  

以此就相比好通晓了,该结构体包含了办法的名号(SEL),方法的项目以及艺术的IMP。

5. 消息

在Objective-C中,音信直到运行时才将其与音讯的实现绑定,编译器会将

[receiver message];

转换成

objc_msgSend(receiver,selector);   //1

objc_msgSend(receiver,selector,arg1,arg2,...);  //2

万一含有参数,那么就会实施2措施。其实除了该方法,还有以下多少个章程:

objc_msgSend_stret    
objc_msgSendSuper
objc_msgSendSuper_stret

当想一个目标的父类发送message时,会采用

objc_msgSendSuper

假若措施的再次来到值是一个结构体,那么就会采用

objc_msgSend_stret
objc_msgSendSuper_stret

这里我们得以打开objc源码,然后您会发现中间有三个.s文件:
图片 8
此间之所以有objc-msg-类的不等文件,我揣测应该是对两样的CPU指令集(指令不相同)做了分别处理。因为这些.s文件名称中带有的是见仁见智的arm指令集。而且打开.s文件你会意识内部的落实是汇编语言,所以苹果为了功用依然蛮拼的,直接用汇编语言实现。
内部就能找到objc _ msgSend的实现(objc-msg-i386.s中):
图片 9
虽说对汇编通晓不是太多,可是这一个文件中的注释很详细,从注释可以看出objc_msgSend方法的执行进程:

  1. 先加载receiver和selector到寄存器,然后判断receiver是否为空,假诺为空,则函数执行完毕;
  2. 一旦receiver不为空,先河搜索缓存,查看方法缓存列表里面是不是有改selector,假如有则进行;
  3. 若是没有缓存,则搜索方法列表,要是在模式列表中找到,则跳转到具体的imp实现。没有则履行完毕。

前言

从字面意思看,就是运行时。不过那个运行时到底什么样看头?可以把它掌握成:不是在编译期也不是在链接期,而是在运行时。这到底在运作期间做了什么样吗?依照苹果官方的布道,就是把有些核定(方法的调用,类的增长等)推迟,推迟到运行期间。只要有可能,程序就可以动态的做到任务,而不是我们在编译期已经决定它要水到渠成什么任务。这就代表了OC不仅仅需要编译器,还需要一个运转时的系统来襄助。

NSObject的一对办法

在Foundation框架之中有个NSObject.h,在usr/include/objc里面也有一个NSObject.h。而我辈一向应用的类的基类是/usr/include/objc里面的这一个NSObject.h,Foundation里面的NSObject.h只是NSObject的一个Category。所以那边我们更珍惜一下/usr/include/objc里面的NSObject.h。
出于多数对象都是NSObject的子类,所以在NSObject.h里面定义的措施都得以采取。
在那些措施里面,有一部分艺术可以查询runtime系统的音讯,例如:

- (BOOL)isKindOfClass:(Class)aClass;   //用来检测一个对象是否是某各类的实例对象,aClass也有可能是父类,同样可以检测出来。
- (BOOL)isMemberOfClass:(Class)aClass;   //而该方法只能检测一个对象是否是某各类的实例对象。但如果aClass不能为该类的父类,如果是父类则该方法返回NO

- (BOOL)respondsToSelector:(SEL)aSelector;

- (BOOL)conformsToProtocol:(Protocol *)aProtocol;

- (IMP)methodForSelector:(SEL)aSelector;

此处用代码对isKindOfClass和isMemberOfClass做个简易介绍:

//stu是Student的实例对象,Student的父类为Person,Person的父类为NSObject。
[stu isKindOfClass:[Student class]];    //YES
[stu isKindOfClass:[Person class]];    //YES
[stu isKindOfClass:[NSObject class]];   //YES

[stu isMemberOfClass:[Student class]];    //YES
[stu isMemberOfClass:[Person class]];    //NO
[stu isMemberOfClass:[NSObject class]];   //NO

咱俩得以在objc源代码中的NSObject.mm中看到相应的兑现:

+ (BOOL)isMemberOfClass:(Class)cls {
    return object_getClass((id)self) == cls;
}
- (BOOL)isMemberOfClass:(Class)cls {
    return [self class] == cls;
}
+ (BOOL)isKindOfClass:(Class)cls {
    for (Class tcls = object_getClass((id)self); tcls; tcls = tcls->superclass) {
        if (tcls == cls) return YES;
    }
    return NO;
}
- (BOOL)isKindOfClass:(Class)cls {
    for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
        if (tcls == cls) return YES;
    }
    return NO;
}

从实际落实可知,为何isKindOfClass可以检测出superclass。其它,在NSObject.h中,并没有看出两个主意的类措施阐明,不过在落实里面却蕴藏了类模式的落实。这里有个问题:为啥没有对外宣示的多少个类模式依然得以在表面调用呢?(比如自己可以直接行使[Student
isMemberOfClass:[NSObject class]])

此地还用到了class方法,那么些点子阐明如下:

+ (Class)class OBJC_SWIFT_UNAVAILABLE("use 'aClass.self' instead");

- (Class)class OBJC_SWIFT_UNAVAILABLE("use 'type(of: anObject)' instead");

+ (Class)class {   //返回当前的self
    return self;
}

- (Class)class {
    return object_getClass(self);
}

这里根本的是明亮self究竟代表着怎么样:

  1. 当self为实例对象的时候,[self class] 和
    object_getClass(self)是等价的。object_getClass([self
    class])得到的是元类。
  2. 当self为类对象的时候,[self
    class]回去的是本人,依然self。object_getClass(self)
    与object_getClass([self class])等价。得到的是元类。
Ivar

Ivar从字面意思来讲,它就是表示的实例变量,它也是一个结构体指针,包含了变量的称号、类型、偏移量以及所占空间。

OC源代码

大多数情状下,我们写的OC代码,其实它底层的实现就是runtime。runtime系统在偷偷摸摸自动帮我们处理了操作。例如我们编译一个类,编译器器会创制一个结构体,然后这多少个布局体会从类中捕获信息,包括方法、属性、Protocol等。

给Category添加属性

我们可以运用runtime在Category中给类添加属性,这些关键接纳了多少个runtime钟的方法:

OBJC_EXPORT void
objc_setAssociatedObject(id _Nonnull object, const void * _Nonnull key,id _Nullable value, objc_AssociationPolicy policy);

OBJC_EXPORT id _Nullable
objc_getAssociatedObject(id _Nonnull object, const void * _Nonnull key);

切切实举行使可参见:给分类(Category)添加属性

动态方法分析

在支付进程中,你或许想动态地提供一个主意的贯彻。比如我们对一个目标讲明了一个性质,然后我们运用了
@dynamic 标识符:

@dynamic propertyName;

该标识符的目的就是告诉编译器:和那些特性相关的getter和setter方法会动态地提供(当然你也得以一直手动在代码里面实现)。那多少个时候你就会用到NSObject.h里面的五个点子

+ (BOOL)resolveClassMethod:(SEL)sel OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
+ (BOOL)resolveInstanceMethod:(SEL)sel OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

来提供格局的贯彻。
实际上OC方法就是一个简约的C函数,它起码含有了六个参数self和 _
cmd,你能够协调注解一个主意:

void dynamicMethodIMP(id self, SEL _cmd) {
    //这里是方法的具体实现
}

这会儿我们得以在表明属性的类中实现地点提到的多少个措施(一个是解析类方法,一个是分析实例方法),例如我在Person里面这么写:

@dynamic address;   //也就意味着我们需要手动/动态实现该属性的getter和setter方法。

你会发现当大家运行下面的代码时,程序会crash:

   Person *zhangsan = [[Person alloc] init];
    zhangsan.address = @"he nan xinxiang ";

    NSLog(@"%@",zhangsan.address);

//    crash reason
// -[Person setAddress:]: unrecognized selector sent to instance 0x1d4449630

这里大概的做一个动态方法分析:

void setter(id self,SEL _cmd) {
    NSLog(@"set address");
}

+ (BOOL)resolveInstanceMethod:(SEL)sel {
    NSString *selStr = NSStringFromSelector(sel);
    if ([selStr hasPrefix:@"set"]) {
        class_addMethod([self class], sel, (IMP)setter, "v@:");
        return YES;
    }
    return [super resolveInstanceMethod:sel];
}

为此我们需要团结去贯彻setAddress:
方法。(这里判断用hasPrefix不太规范,开发者能够自动遵照需要调整)。转发消息(下边会讲到)和动态解析是正交的。也就是说一个class有机会再消息转发机制前去动态解析此措施,也可以将动态解析方法重临NO,然后将操作转发给信息转发。

动态加载

OC编程也同意我们在程序运行的时候动态去创设和链接一个类如故分类。这些成立的类依旧分类将会和运行app前创办的类一样,没有区别。
动态加载在付出的长河中可以做过多业务,例如系统安装中的不同模块就是动态加载的。
在Cocoa环境中,最经典的就是Xcode,它可以设置不同的插件,这么些也是动态加载的办法实现的。

8. Runtime的施用情形

Runtime的拔取几乎无处不在,OC本身就是一门运行时语言,Class的成形、方法的调用等等,都是Runtime。此外,我们可以用Runtime做一些别样的事情。

Runtime函数

runtime系统实际就是一个动态共享的Library,它是由在/usr/include/objc目录的公物接口中的函数和数据结构组成。
图片 10

3.runtime.h解析

俺们先看一下在usr/include/objc/runtime.h,这多少个是其它一个工程都得以直接找到的,它是SDK的一部分。紧要定义了以下内容:

  1. 概念了一部分类别,例如Method/Ivar/Category等,还有一对结构体。
  2. 函数。函数里面有分了几大类:
    • 至于目标实例的艺术,例如object _ getClass、object _
      setClass以及object _ getIvar等。那一个函数大多以object开头
      用来博取属性或者对目标举行操作。
    • 收获类定义的点子,例如objc _ getClass/objc _
      getMetaClass等,那些措施更多的是获取Class或者在Class级别上举办操作。
      多以objc开头
    • 和类相关的格局。例如class _ getName/class _
      isMetaClass等,这些更多的是获取Class的一对属性。比如该类的习性列表、方法列表、协议列表等。传参大多为Class。
      多以class开头
    • 实例化类的有的主意。例如class _
      createInstance方法,就是一定于平时的alloc init。
    • 添加类的方法。例如你可以使用这一个方法春天的登记一个类。使用objc
      _ allocateClassPair创制一个新类,使用 objc _
      registerClassPair对类举办注册
    • 等等。。。
  3. 除此以外就是有的舍弃的艺术和系列。

目录

接下去就对Runtime做一个系统的介绍,首要内容包括:

  1. 简介
  2. 涉嫌到的数据结构
  3. runtime.h解析
  4. 何以得以触发到Run提姆e?
  5. 消息
  6. 动态新闻分析
  7. 新闻转发
  8. Runtime的应用境况

总结

Objective-c本身就是一门秋天语言,所以了然runtime有助于我们更加深入地通晓其中间的贯彻原理。也会把一些接近很难的问题通过runtime很快解决。

参照链接:

1.Objective-C Runtime Programming
Guide

2.Objective-C
Runtime

3.objc4
4.初叶明白信息的传递和中转
5.class_copyIvarList方法得到实例变量问题引发的思辨
6.JSPatch
实现原理详解

7.给分类(Category)添加属性
8.Method Swizzling

转载请注脚来源:http://www.cnblogs.com/zhanggui/p/8243316.html

6. 动态信息分析

此地介绍一下一旦动态地提供格局的落实。

Class

它是一个objc_class的结构体指针,在runtime.h中的定义如下:

/// An opaque type that represents an Objective-C class.一个不透明类型,代表OC的类
typedef struct objc_class *Class;

struct objc_class {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;

#if !__OBJC2__
    Class _Nullable super_class                              OBJC2_UNAVAILABLE;
    const char * _Nonnull name                               OBJC2_UNAVAILABLE;
    long version                                             OBJC2_UNAVAILABLE;
    long info                                                OBJC2_UNAVAILABLE;
    long instance_size                                       OBJC2_UNAVAILABLE;
    struct objc_ivar_list * _Nullable ivars                  OBJC2_UNAVAILABLE;
    struct objc_method_list * _Nullable * _Nullable methodLists                    OBJC2_UNAVAILABLE;
    struct objc_cache * _Nonnull cache                       OBJC2_UNAVAILABLE;
    struct objc_protocol_list * _Nullable protocols          OBJC2_UNAVAILABLE;
#endif

} OBJC2_UNAVAILABLE;

该结构体中各部分介绍如下:

  • isa:是一个Class类型的指针,每个对象的实例都有isa指针,他针对性对象的类。而Class里面也有个isa指针,它指向meteClass(元类),元类保存了类措施的列表。
  • name:对象的名字
  • version:类的版本号,必须是0
  • info:供运行期间利用的位标识
  • instance_size:该类的实例大小
  • ivars:成员变量数组,包含了此类包含的成员变量
  • methodLists:包含方法的数组列表,也是一个结构体,该结构体里面还含有了一个obsolete的指针,表示放任的法子的列表
  • cache:缓存。这一个相比较复杂,在末端会波及,这里先忽略。
  • protocols:协议列表,也是一个数组

而在objc-runtime-new.h中,你会发现这样的定义(在runtime中并从未完全透露objc_class的实现):

struct objc_class : objc_object {
    // Class ISA;
    Class superclass;
    cache_t cache;             // formerly cache pointer and vtable
    class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags

    class_rw_t *data() { 
        return bits.data();
    }
    //其他的省略

其实objc _ class继承自objc _
object。所以这也证实了为什么id可以转移为任何的品种。

Method Swizzling

它是改变一个已存在的selector的实现的技术,比如您想将viewDidload方法替换为大家自定义的形式,给系统的情势添加一些内需的功力,来贯彻某些需求。比如你想跟踪每个ViewController展示的次数,你可以应用该技能重写ViewDidAppear方法,然后做一些融洽的处理。可以参见Method
Swizzling
其间的讲解。

4. 什么得以触发到Run提姆(Tim)e?

有两种不同的形式得以让OC编程和runtime系统互相。

热更新(JSPatch的实现)

JSPatch能成功JS调用和改写OC方法的根本原因就是OC是动态语言,OC上的具有办法的调用/类的生海得拉巴通过OC
Runtime在运行时开展,我们可以依据名称/方法名反射拿到相应的类和情势。例如

Class class = NSClassFromString("UIViewController");
id viewController = [[class alloc] init];
SEL selector = NSSelectorFromString("viewDidLoad");
[viewController performSelector:selector];

也正是鉴于此,才促成了热更新。

行使了隐藏参数

在发送一个音讯的时候,会被编译成objc_msgSend,此时该音信的参数将会传出objc_msgSend方法里面。除此之外,还会含有五个暗藏的参数:

  1. receiver
  2. method的selector

那多个参数在下面也有提到。其中的receiver就是音讯的发送方,而selector就是接纳器,也足以间接用
_ cmd来指代( _
cmd用来代表当前所在艺术的SEL)。之所以隐蔽是因为在格局讲明中并不曾被醒目宣示,在源代码中我们依然可以引用它们。

SEL

选拔器,每个方法都有和好的选用器,其实就是方法的名字,可是不仅仅是办法的名字,在objc.h中,大家得以看看它的定义:

/// An opaque type that represents a method selector.一个不透明类型,用来代表一个方法选择器
typedef struct objc_selector *SEL;

由定义可知它是一个objc_selector的结构体指针,难堪的是在runtime源码中并不曾找到该结构体。估计它里面应该就是一个char
的字符串。
您可以选用:

 NSLog(@"%s",@selector(description));  //%s用来输出一个字符串

打印出来description。
在此地你可以把它知道成一个选用器,可以标识某个方法。

字典转换Model

平生大家从服务端得到的数量是json字符串,我们得以将其转换成成NSDictionary,然后通过runtime中的一些办法做一个变换:
先得到model的具有属性或者成员变量,然后将其和字典中的key做映射,然后经过KVC对性能赋值即可。更多可参见class_copyIvarList方法赢得实例变量问题引发的研商中的例子。

7. 音讯转发

发送一个音信给目的,倘诺目标不可以处理,那么就会发出错误。但是,在暴发错误此前,runtime
系统会给目的第二次机会去处理该新闻。这里详细已经在起先领会信息的传递和转账作品中做了介绍,这里就不再介绍了。

2.关乎到的数据结构

此地重要介绍一下在runtime.h里面涉及到的一部分数据结构。

平台

HTC的应用程序以及OS X
v10.5本子的64位机器使用的是modern版本的runtime。
此外(OS X桌面应用32位程序)使用的是legacy版本的runtime。

1.简介

基于前言,你早已了然了Runtime大概是个什么样鬼,在OC发展过程中,它紧要有三个版本:Legacy和Modern。Legacy版本拔取的是OC1.0本子;Modern版本采纳的OC2.0版本,而且相比较Legacy也添加了有的新特色。最明确的区分在于:

  • 在legacy版本,即便您转移了类的布局,那么你必须另行编译继承自它的类。
  • 在modern版本,假设您转移了类的布局,你不用再次编辑继承自它的类。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图