美文网首页
RxSwift(10)中介者

RxSwift(10)中介者

作者: 忆痕无殇 | 来源:发表于2019-08-13 21:08 被阅读0次
      func deallocDemo() {
            _ = rx.deallocating.subscribe(onNext :{() in
                print("nihao")
            }  )
        }
    

    走到deallocating的getter方法

      public var deallocating: Observable<()> {
            return self.synchronized {
                do {
                    let proxy: DeallocatingProxy = try self.registerMessageInterceptor(deallocSelector)
                    return proxy.messageSent.asObservable()
                }
                catch let e {
                    return Observable.error(e)
                }
            }
        }
    
    

    dealloc来自Reactive的扩展extension Reactive where Base: AnyObject针对于NSObject,所以只要是NSObject都支持deallocating方法。

      public var deallocating: Observable<()> {
            return self.synchronized {
                do {
                    let proxy: DeallocatingProxy = try self.registerMessageInterceptor(deallocSelector)
                    return proxy.messageSent.asObservable()
                }
                catch let e {
                    return Observable.error(e)
                }
            }
        }
    

    proxyclass类型由self.registerMessageInterceptor(deallocSelector)创建序列返回proxy.messageSent.asObservable()messageSent发送序列

     @objc func deallocating() {
                self.messageSent.on(.next(()))//③*发送序列*
            }
    

    deallocSelectorprivate let deallocSelector = NSSelectorFromString("dealloc")``dealloc方法
    这里需要注意:为啥要通过string来拿dealloc方法?
    因为dealloc方法无法通过@selector进行重写。系统的析构函数不允许重写。所以通过string进行获取。
    _ = rx.deallocating.subscribe进行序列的②订阅
    ①②③是序列的基本流程。

    observe流程.jpg

    问题:怎么交换方法?swizzing
    let targetImplementation = RX_ensure_observing(self.base, selector, &error)ensure_observing重点在这。添加了对dealloc的观察。来到里面看到

       [[RXObjCRuntime instance] performLocked:^(RXObjCRuntime * __nonnull self) {
                    targetImplementation = [self ensurePrepared:target
                                                   forObserving:selector
                                                          error:error];
                }];
    

    RXObjCRuntime来到OCruntime。通过performLocked加锁安全处理。

    -(void)performLocked:(void (^)(RXObjCRuntime* __nonnull))action {
        pthread_mutex_lock(&_lock);
        action(self);
        pthread_mutex_unlock(&_lock);
    }
    

    来到ensurePrepared方法找到了swizzleDeallocating,点击进入

    SWIZZLE_INFRASTRUCTURE_METHOD(
        void,
        swizzleDeallocating,
        ,
        deallocSelector,
        DEALLOCATING_BODY
    )
    

    点击进入宏定义SWIZZLE_INFRASTRUCTURE_METHOD里面是实现交换方法的代码。被宏定义了。

    #define SWIZZLE_INFRASTRUCTURE_METHOD(return_value, method_name, parameters, method_selector, body, ...)               \
        SWIZZLE_METHOD(return_value, -(BOOL)method_name:(Class __nonnull)class parameters error:(NSErrorParam)error        \
            {                                                                                                              \
                SEL selector = method_selector; , body, NO_BODY, __VA_ARGS__)                                              \
    
    
    // common base
    
    #define SWIZZLE_METHOD(return_value, method_prototype, body, invoked_body, ...)                                          \
    method_prototype                                                                                                         \
        __unused SEL rxSelector = RX_selector(selector);                                                                     \
        IMP (^newImplementationGenerator)(void) = ^() {                                                                          \
            __block IMP thisIMP = nil;                                                                                       \
            id newImplementation = ^return_value(__unsafe_unretained id self DECLARE_ARGUMENTS(__VA_ARGS__)) {               \
                body(__VA_ARGS__)                                                                                            \
                                                                                                                             \
                struct objc_super superInfo = {                                                                              \
                    .receiver = self,                                                                                        \
                    .super_class = class_getSuperclass(class)                                                                \
                };                                                                                                           \
                                                                                                                             \
                return_value (*msgSend)(struct objc_super *, SEL DECLARE_ARGUMENTS(__VA_ARGS__))                             \
                    = (__typeof__(msgSend))objc_msgSendSuper;                                                                \
                @try {                                                                                                       \
                  return msgSend(&superInfo, selector ARGUMENTS(__VA_ARGS__));                                               \
                }                                                                                                            \
                @finally { invoked_body(__VA_ARGS__) }                                                                       \
            };                                                                                                               \
                                                                                                                             \
            thisIMP = imp_implementationWithBlock(newImplementation);                                                        \
            return thisIMP;                                                                                                  \
        };                                                                                                                   \
                                                                                                                             \
        IMP (^replacementImplementationGenerator)(IMP) = ^(IMP originalImplementation) {                                     \
            __block return_value (*originalImplementationTyped)(__unsafe_unretained id, SEL DECLARE_ARGUMENTS(__VA_ARGS__) ) \
                = (__typeof__(originalImplementationTyped))(originalImplementation);                                         \
                                                                                                                             \
            __block IMP thisIMP = nil;                                                                                       \
            id implementationReplacement = ^return_value(__unsafe_unretained id self DECLARE_ARGUMENTS(__VA_ARGS__) ) {      \
                body(__VA_ARGS__)                                                                                            \
                @try {                                                                                                       \
                    return originalImplementationTyped(self, selector ARGUMENTS(__VA_ARGS__));                               \
                }                                                                                                            \
                @finally { invoked_body(__VA_ARGS__) }                                                                       \
            };                                                                                                               \
                                                                                                                             \
            thisIMP = imp_implementationWithBlock(implementationReplacement);                                                \
            return thisIMP;                                                                                                  \
        };                                                                                                                   \
                                                                                                                             \
        return [self ensureSwizzledSelector:selector                                                                         \
                                    ofClass:class                                                                            \
                 newImplementationGenerator:newImplementationGenerator                                                       \
         replacementImplementationGenerator:replacementImplementationGenerator                                               \
                                      error:error];                                                                          \
     }                                                                                                                       \
    
    

    去掉“\”之后就是实现的代码了。通过ensureSwizzledSelector方法进行交换。

    -(BOOL)ensureSwizzledSelector:(SEL __nonnull)selector
                          ofClass:(Class __nonnull)class
       newImplementationGenerator:(IMP(^)(void))newImplementationGenerator
    replacementImplementationGenerator:(IMP (^)(IMP originalImplementation))replacementImplementationGenerator
                            error:(NSErrorParam)error {
        if ([self interceptorImplementationForSelector:selector forClass:class] != nil) {
            DLOG(@"Trying to register same intercept at least once, this sounds like a possible bug");
            return YES;
        
    

    通过IMP进行两者的互换。
    原因是1:因为swift特性,无法动态的编译。达到预编译的效果。
    2:速度快。

    问题:什么时候调用的deallocating?

    #define DEALLOCATING_BODY(...)                                                        \
        id<RXDeallocatingObserver> observer = objc_getAssociatedObject(self, rxSelector); \
        if (observer != nil && observer.targetImplementation == thisIMP) {                \
            [observer deallocating]; //这里调用了     deallocating                                                \
        }
    

    相关文章

      网友评论

          本文标题:RxSwift(10)中介者

          本文链接:https://www.haomeiwen.com/subject/eufsjctx.html