既是类, 又是协议?
@protocol RACSubscriber <NSObject>
/////真正的订阅者。存储了3个block
@interface RACSubscriber : NSObject <RACSubscriber>
@interface RACPassthroughSubscriber : NSObject <RACSubscriber>
@interface RACSubject<ValueType> : RACSignal<ValueType> <RACSubscriber>
@interface RACChannelTerminal<ValueType> : RACSignal<ValueType> <RACSubscriber>
说明不是所有的订阅者都是RACSubscriber类,还有一些只是继承了这个协议的类,但是他并不是RACSubscriber类。
@protocol NSObject
@interface NSObject <NSObject>
@interface NSProxy <NSObject>
不是所有的对象都是NSObject类,还有一些对象,他的类是继承了NSObject这个协议的,但是他并不是
NSObject类,
有一个特点是:
1、 这个类同时继承这个协议。
2、 这个协议还会被其他类继承。这个其它类和类具有协议所规定的相同的接口。
他们具有不同的有协议规定之外的东西---属性/成员/方法/类方法等。
有什么好处?
http://www.cocoachina.com/ios/20141018/9960.html
https://blog.csdn.net/c395565746c/article/details/8507008

消息发送
1,转化为objc_msgSend(obj, @selector());
2,通过obj的isa找到Class
3,在Class的cache中查找method
4,在Class的methodList中查找method
5,在Class的父类,中执行3,4;直到根类;根类(NSObject/NSProxy都是根类)的父类是nil终止。
6,找到后,加入到cache,并跳转到对应的函数中去执行。
struct objc_class {
Class isa; // 指向metaclass
Class super_class ; // 指向其父类
const char *name ; // 类名
long version ; // 类的版本信息,初始化默认为0,可以通过runtime函数class_setVersion和class_getVersion进行修改、读取
long info; // 一些标识信息,如CLS_CLASS (0x1L) 表示该类为普通 class ,其中包含对象方法和成员变量;CLS_META (0x2L) 表示该类为 metaclass,其中包含类方法;
long instance_size ; // 该类的实例变量大小(包括从父类继承下来的实例变量);
struct objc_ivar_list *ivars; // 用于存储每个成员变量的地址
struct objc_method_list **methodLists ; // 与 info 的一些标志位有关,如CLS_CLASS (0x1L),则存储对象方法,如CLS_META (0x2L),则存储类方法;
struct objc_cache *cache; // 指向最近使用的方法的指针,用于提升效率;
struct objc_protocol_list *protocols; // 存储该类遵守的协议
};
当向Objective-C对象发送一个消息,但runtime在当前类及父类中找不到此selector对应的方法时,消息转发(message forwarding)流程开始启动。
消息转发
1、动态方法解析(Dynamic Method Resolution或Lazy method resolution)
向当前类(Class)发送resolveInstanceMethod:(对于类方法则为resolveClassMethod:)消息,如果返回YES,则系统认为请求的方法已经加入到了,则会重新发送消息。
+(BOOL)resolveInstanceMethod:(SEL)sel
+(BOOL)resolveClassMethod:(SEL)sel
2、快速转发路径(Fast forwarding path)
若果当前target实现了forwardingTargetForSelector:方法,则调用此方法。如果此方法返回除nil和self的其他对象,则向返回对象重新发送消息。
-(id)forwardingTargetForSelector:(SEL)aSelector
3、慢速转发路径(Normal forwarding path)
首先runtime发送methodSignatureForSelector:消息查看Selector对应的方法签名,即参数与返回值的类型信息。如果有方法签名返回,runtime则根据方法签名创建描述该消息的NSInvocation,向当前对象发送forwardInvocation:消息,以创建的NSInvocation对象作为参数;若methodSignatureForSelector:无方法签名返回,则向当前对象发送doesNotRecognizeSelector:消息,程序抛出异常退出。
-(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
-(void)forwardInvocation:(NSInvocation *)anInvocation