RACSubscriber
@protocol RACSubscriber <NSObject>
首先这个是一个协议
subscribe 订阅 ,故名思义,这是一个传递信号的。也就是rac的数据流是用这个传递的。在rac的地位,是NO.1。
/// Represents any object which can directly receive values from a RACSignal.
///
/// You generally shouldn't need to implement this protocol. +[RACSignal
/// createSignal:], RACSignal's subscription methods, or RACSubject should work
/// for most uses.
///
/// Implementors of this protocol may receive messages and values from multiple
/// threads simultaneously, and so should be thread-safe. Subscribers will also
/// be weakly referenced so implementations must allow that.
代表一个可以可以直接接收Signal发送的数据的物。
通常不需要实现这个协议。
这个协议的实现者可以同时从多线程接收信息和数据,并且是线程安全的。
订阅者是弱引用,所以实现者必须允许。
发送下一个值value到订阅者
- (void)sendNext:(nullable id)value;
这会终止订阅并使订阅者失效,相当于断开订阅行为,将来也收不到订阅信号。
- (void)sendError:(nullable NSError *)error;
这个和上一个差不多,只是没有error
- (void)sendCompleted;
给订阅者发送代表众多订阅之一的一次性信号
- (void)didSubscribeWithDisposable:(RACCompoundDisposable *)disposable;
@end
以上给出了这个协议的全部内容。
下面分析实现部分
奇怪了。
RACSubscriber ,这个是协议,为何会有接口和实现呢。
@interface RACSubscriber : NSObject <RACSubscriber> 这个声明是在"RACSubscriber+Private.h"的。这就说明了,它既是协议名,也是类名。
#import "RACSubscriber.h"
// A simple block-based subscriber.
@interface RACSubscriber : NSObject <RACSubscriber>
// Creates a new subscriber with the given blocks.
+ (instancetype)subscriberWithNext:(void (^)(id x))next error:(void (^)(NSError *error))error completed:(void (^)(void))completed;
@end
![](https://img.haomeiwen.com/i1475721/e2e14152ce3a7b63.png)
引读:(为何OC中协议和类名可以同名)
与此写法有常见的NSObject ,如上:@protocol RACSubscriber < NSObject >
我们在.m中发现:
- (void)sendError:(NSError *)e {
@synchronized (self) {
void (^errorBlock)(NSError *) = [self.error copy];
[self.disposable dispose];
if (errorBlock == nil) return;
errorBlock(e);
}
}
- (void)sendCompleted {
@synchronized (self) {
void (^completedBlock)(void) = [self.completed copy];
[self.disposable dispose];
if (completedBlock == nil) return;
completedBlock();
}
}
引证了上面的猜测,都会执行[self.disposable dispose];
RACDisposable 这个类,非常难懂。
/// A disposable encapsulates the work necessary to tear down and cleanup a
/// subscription.
一次性容器封裝了拆除和清理訂閱所需的工作。
void * volatile _disposeBlock; //volatile 易挥发的
对一个变量加上Volatile关键字可以迫使编译器每次都重新从内存中加载该变量,而不会从寄存器中加载。当一个变量的值可能随时会被一个外部源改变时,应该将该变量声明为Volatile。
网友评论