RxSwift(10)中介者
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)
}
}
}
proxy
class类型由self.registerMessageInterceptor(deallocSelector)
① 创建序列返回proxy.messageSent.asObservable()
。messageSent
发送序列
@objc func deallocating() {
self.messageSent.on(.next(()))//③*发送序列*
}
deallocSelector
是private let deallocSelector = NSSelectorFromString("dealloc")``dealloc
方法
这里需要注意:为啥要通过string
来拿dealloc
方法?
因为dealloc
方法无法通过@selector
进行重写。系统的析构函数不允许重写。所以通过string进行获取。
在_ = rx.deallocating.subscribe
进行序列的②订阅
①②③是序列的基本流程。
问题:怎么交换方法?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
来到OC
的runtime
。通过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 \
}