RxSwift-中介者模式 Swift版
1、方法一 didMoveToParentViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(fireHome) userInfo:nil repeats:YES];
}
- (void)didMoveToParentViewController:(UIViewController *)parent{
if (parent == nil) {
[self.timer invalidate];
self.timer = nil;
}
NSLog(@"我走了");
}
- (void)fireHome{
num++;
NSLog(@"hello word - %d",num);
}
- (void)dealloc{
NSLog(@"%s",__func__);
}
2、方法二 block
- (void)viewDidLoad {
[super viewDidLoad];
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {
NSLog(@"hello word - ");
}];
}
- (void)dealloc{
[self.timer invalidate];
self.timer = nil;
NSLog(@"%s",__func__);
}
3、方法三 引入中间变量
@property (nonatomic, strong) id target;
- (void)viewDidLoad {
[super viewDidLoad];
self.target = [[NSObject alloc] init];
class_addMethod([self.target class], @selector(fireHomedyz), (IMP)fireHomeFunc, "v@:");
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self.target selector:@selector(fireHomedyz) userInfo:nil repeats:YES];
}
void fireHomeFunc(){
NSLog(@"%s",__func__);
}
- (void)dealloc{
[self.timer invalidate];
self.timer = nil;
NSLog(@"%s",__func__);
}
3、方法三 引入中间层
- (void)viewDidLoad {
[super viewDidLoad];
//self -> timerWapper(释放不了) </-/> timer <- runloop
self.timerWapper = [[LGTimerWapper alloc] lg_initWithTimeInterval:1 target:self selector:@selector(fireHome) userInfo:nil repeats:YES];
}
- (void)fireHome{
num++;
NSLog(@"hello word - %d",num);
}
- (void)dealloc{
[self.timerWapper lg_invalidate];
NSLog(@"%s",__func__);
}
//LGTimerWapper.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface LGTimerWapper : NSObject
- (instancetype)lg_initWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;
- (void)lg_invalidate;
@end
NS_ASSUME_NONNULL_END
//LGTimerWapper.m
#import "LGTimerWapper.h"
@interface LGTimerWapper()
@property (nonatomic, weak) id target;
@property (nonatomic, assign) SEL aSelector;
@property (nonatomic, strong) NSTimer *timer;
@end
@implementation LGTimerWapper
- (instancetype)lg_initWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo{
if (self == [super init]) {
self.target = aTarget;
self.aSelector = aSelector;
self.timer = [NSTimer scheduledTimerWithTimeInterval:ti target:self selector:@selector(fireHome) userInfo:userInfo repeats:yesOrNo];
}
return self;
}
- (void)fireHome{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
// 让编译器出栈,恢复状态,继续编译后续的代码!
if ([self.target respondsToSelector:self.aSelector]) {
[self.target performSelector:self.aSelector];
}
#pragma clang diagnostic pop
}
- (void)lg_invalidate{
[self.timer invalidate];
self.timer = nil;
}
- (void)dealloc{
NSLog(@"%s",__func__);
}
@end
3、方法三 中间层 NSProxy
- (void)viewDidLoad {
[super viewDidLoad];
self.proxy = [LGProxy proxyWithTransformObject:self];
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self.proxy selector:@selector(fireHome) userInfo:nil repeats:YES];
}
- (void)fireHome{
num++;
NSLog(@"hello word - %d",num);
}
- (void)dealloc{
[self.timer invalidate];
self.timer = nil;
NSLog(@"%s",__func__);
}
//LGProxy.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface LGProxy : NSProxy
+ (instancetype)proxyWithTransformObject:(id)object;
@end
NS_ASSUME_NONNULL_END
//LGProxy.m
#import "LGProxy.h"
@interface LGProxy()
@property (nonatomic, weak) id object;
@end
@implementation LGProxy
+ (instancetype)proxyWithTransformObject:(id)object{
LGProxy *proxy = [LGProxy alloc];
proxy.object = object;
return proxy;
}
// sel - imp -
// 消息转发 self.object
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel{
if (self.object) {
}else{
NSLog(@"麻烦收集 stack");
}
return [self.object methodSignatureForSelector:sel];
}
- (void)forwardInvocation:(NSInvocation *)invocation{
if (self.object) {
[invocation invokeWithTarget:self.object];
}else{
// add imp - 动态创建 - imp
// imp 常规 -- pop
// 收集奔溃信息
NSLog(@"麻烦收集 stack");
}
}
@end