当前位置: 首页 > news >正文

济南建站模板/百度运营怎么做

济南建站模板,百度运营怎么做,大连德泰建设,以及在增加外链时应当注意什么?原文链接 开发过程中我们必不可少的需要接触定时器,在iOS中,常用的定时器有以下几种: GCD TimerCADisplayLinkNSTimer这里我们主要来看下 NSTimer 的一个问题 #import "ViewController.h"interface ViewController ()property (non…

原文链接

开发过程中我们必不可少的需要接触定时器,在iOS中,常用的定时器有以下几种:

  • GCD Timer
  • CADisplayLink
  • NSTimer

这里我们主要来看下 NSTimer 的一个问题

#import "ViewController.h"@interface ViewController ()@property (nonatomic, strong) NSTimer *t;@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];
}- (void)startTImer {_t = [NSTimer timerWithTimeInterval:1.0f target:self selector:@selector(someBussiness) userInfo:nil repeats:true];[[NSRunLoop currentRunLoop] addTimer:_t forMode:NSRunLoopCommonModes];
}- (void)someBussiness {NSLog(@"timer triggered");
}- (void)dealloc {NSLog(@"Controller dealloc");if (self.t) {[self.t invalidate];}
}- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {if (self.presentingViewController) {[self dismissViewControllerAnimated:true completion:nil];}else {ViewController *vc = ViewController.new;vc.view.backgroundColor = UIColor.grayColor;[self presentViewController:vc animated:true completion:nil];[vc startTImer];}
}@end
复制代码

这里在我们点击页面之后,会present出来一个新页面,并开始使用 NSTimer 计时,并在 dealloc 中打印信息。 再次点击present出来的viewController把当前的Controller销毁掉。

再次点击我们会发现,计时器并没有停止,而且预期的dealloc中的信息也并没有打印,这是为什么呢?

这里我们可以使用Xcode的 Debug Memory Graph ,就在下方控制台上面的按键里面,可以看到如图所示

我们可以看到这里 Runloop 引用了 timer ,而 timer 又引用了当前的Controller,最终导致Controller无法释放

我们通常会想,那把 NSTimer 的 property 用weak来修饰,或者把timer的target使用 weak 修饰不就好了吗。那我们来修改一下代码

@property (nonatomic, weak) NSTimer *t;- (void)startTImer {__weak typeof(self) ws = self;_t = [NSTimer timerWithTimeInterval:1.0f target:ws selector:@selector(someBussiness) userInfo:nil repeats:true];[[NSRunLoop currentRunLoop] addTimer:_t forMode:NSRunLoopCommonModes];
}
复制代码

这里我们修改timer的property为weak,把target也修饰为weak,再次运行。

哈 , 还是没有释放,timer 仍在打印。

这里其实是因为Runloop会对加入的Timer自动强引用 , 而timer会对target进行强引用,即使修饰为weak也没用,那么,有咩有什么办法来释放他呢?

- (void)startTImer {__weak typeof(self) ws = self;_t = [NSTimer timerWithTimeInterval:1.0f repeats:true block:^(NSTimer * _Nonnull timer) {[ws someBussiness];}];[[NSRunLoop currentRunLoop] addTimer:_t forMode:NSRunLoopCommonModes];
}
复制代码

? ? ? 改为Block调用的方式就可以了,那么有没有别的方式也可以解决这个问题呢?(当然有了要不这篇我tm是在写啥)

NSProxy


An abstract superclass defining an API for objects that act as stand-ins for other objects or for objects that don’t exist yet.

一个抽象超类,用于定义对象的API,这些对象充当其他对象或尚不存在的对象的替身。

官方文档

使用NSProxy我们可以把任意的对象隐藏在后面,由这个抽象类在前面为我们真实的对象代理,当然,我们需要实现两个方法

- (void)forwardInvocation:(NSInvocation *)invocation;
- 
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel;
复制代码

第一个是方法决议,我们可以在这里改变方法的指针,更换方法, 第二个是方法签名,用来提供相应的函数返回类型和参数,

接下来我们新建 TimerProxy 类 继承 NSProxy

TimerProxy.h

#import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGIN@interface TimerProxy : NSProxy+ (instancetype)proxyWithObject:(id)obj;@endNS_ASSUME_NONNULL_END
复制代码

TimerProxy.m

#import "TimerProxy.h"@interface TimerProxy ()@property (nonatomic, weak) id object;@end@implementation TimerProxy- (instancetype)withProxy:(id)obj {_object = obj;return self;
}+ (instancetype)proxyWithObject:(id)obj {return [[self alloc] withProxy:obj];
}- (void)forwardInvocation:(NSInvocation *)invocation {SEL selector = invocation.selector;if ([_object respondsToSelector:selector]) {[invocation invokeWithTarget:_object];}
}- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {return [_object methodSignatureForSelector:sel];
}@end
复制代码

再更新一下viewController的实现

#import "ViewController.h"
#import "TimerProxy.h"@interface ViewController ()@property (nonatomic, strong) NSTimer *t;@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];
}- (void)startTImer {_t = [NSTimer timerWithTimeInterval:1.0f target:[TimerProxy proxyWithObject:self] selector:@selector(someBussiness) userInfo:nil repeats:true];[[NSRunLoop currentRunLoop] addTimer:_t forMode:NSRunLoopCommonModes];
}- (void)someBussiness {NSLog(@"timer triggered");
}- (void)dealloc {NSLog(@"Controller dealloc");if (self.t) {[self.t invalidate];}
}- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {if (self.presentingViewController) {[self dismissViewControllerAnimated:true completion:nil];}else {ViewController *vc = ViewController.new;vc.view.backgroundColor = UIColor.grayColor;[self presentViewController:vc animated:true completion:nil];[vc startTImer];}
}@end
复制代码

应该可以看到正常的dealloc的输出,并且timer也停止了, NSProxy是一个非常有用的抽象类,当然还有其他用途,比如能够模拟多继承,待后续补充。

转载于:https://juejin.im/post/5ca0d4456fb9a05e7b5c5b07

http://www.lbrq.cn/news/1085959.html

相关文章:

  • 做h5网站的公司/网站做外链平台有哪些
  • 做好网站建设静态化/seo网络优化是做什么的
  • 行业用品网站怎么建设外链/微商引流一般用什么软件
  • 古建设计素材网站/宁波核心关键词seo收费
  • 建设电影网站赚钱/培训心得体会800字
  • 做网站要钱的吗/新网域名
  • h5做招聘网站可以吗/免费产品推广软件
  • dw怎么做网站首页/南宁seo优势
  • 贵阳网页网站制作/千锋教育培训多少钱
  • 大连网站设计公司/企业员工培训总结
  • 建设网站必须要服务器吗/企业网站建设模板
  • 枣阳网站开发公司哪家好/惠州seo代理计费
  • wordpress 站点语言/一站式网络营销
  • 网站做研究生毕业论文/营销型网站建设的价格
  • 正规的徐州网站建设/百度推广登录平台app
  • 宁国做网站/平台广告推广
  • 金融互助平台网站制作/站长工具忘忧草社区
  • 网站专题设计欣赏/网站如何在百度刷排名
  • 区块链开发平台/seo人人网
  • 新闻门户网站什么意思/百度信息流推广平台
  • 一个网站做各种好玩的实验/企业seo网络营销
  • 网站直播用php怎么做的/百度搜索大数据
  • 网站对接微信接口/线上销售平台
  • 怎样做班级网站/搜索引擎营销方式
  • 自己编写网站/百度快照什么意思
  • 网站建站东莞/百度网站优化
  • 网站开发怎么自学/seo网站推广计划
  • 网站建设和管理规则/网站seo的优化怎么做
  • 阿里云买域名后怎么做网站/刷关键词排名seo软件软件
  • 走出趣网站怎么做/seo优化百度技术排名教程
  • 自动化测试常用函数
  • springboot基于Java的人力资源管理系统设计与实现
  • 模拟实现python的sklearn库中的Bunch类以及 load_iris 功能
  • CentOS 9 配置国内 YUM 源
  • Keil MDK 嵌入式开发问题:warning: #223-D: function “sprintf“ declared implicitly
  • Java面试宝典:MySQL执行原理二