那些年我们踩过的坑-NSTimer
昨天下午工作的时候遇见一个这样的需求,网络请求失败后把请求数据保存到本地,并自动重发3次,时间间隔是10秒,如果3次后还失败的话,下一次启动这个接口的时候,把新数据和保存在本地的数据都要发送,刚开始以为没多少难度,不就是网络请求发送数据嘛,首先脑子里的第一反应就是用定时器,初始化定时器,然后触发相应的方法,设置请求的次数标志,超过3次停止定时器。事实却证明我还没有理解定时器......
由于是老接口,不能修改,因为产品已经上线,修改会涉及到太多业务,所以只能客户端想办法处理。这样导致的问题就是新数据不能和旧数据一起整合在一起发送,得分两次发送。好吧,那就上吧,我就信心满满的上了。
初始化定时器,遍历本地的数据,分别对应创建一个定时器使用下面的方法,加载到定时器数组
+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo;
然后fire执行。OK,搞定。
bi..bi...bi...bi....bi.....bi......
擦,定时器全乱了,10s内定时器没啥问题,10s后所以定时器都交替进行。。。这不是坑爹么。。。。
吸了口气,喝了一杯水,扫了一眼定时器的代码,灵光一闪,会不会是fire用错了,初始化的时候不要立即执行,等初始化完毕的时候在从数组里面拿出定时器,请求成功或者失败三次后再拿出第二个定时器请求。哈哈哈哈哈哈,应该不会错了,就这么办。
bi....bi.....bi.....bi....bi........
我了个去,稍微好一点了,20秒内的数据是正常的,后面的定时器又交替进行。。。。泥煤呀,甘都得。。。不过已经有进步了,至少20秒是正确的吧,再改改代码应该就可以了,所以立马想一下定时器的执行流程,后来发现会不会是多个定时器和一个定时器的运行是有区别的?因为自己之前基本上都是创建一个定时器就可以了,fire、invalidate使用。没办法,上SOF看看吧。后来才知道原来这两个方法初始化的定时器即使不用fire也会对应的NSTimeInterval后执行,fire只是让他们立即执行,把启动的时间提前到当前,就像一个演唱会本来打算10分钟后开始的,现在因为主唱提前10分钟到了会场,看见粉丝这么热情,提前开始了。
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo; + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo;
可是问题又来了,那既然这样没办法控制定时器的执行,我这个功能岂不是没法做了,有没有什么办法可以控制定时器么,想执行的时候就执行,不想执行的时候就丢掉它。。。。
查找资料的过程中还发现了几个初始化定时器的方法:两个类方法,一个实例方法。
+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo; + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo; - (id)initWithFireDate:(NSDate *)date interval:(NSTimeInterval)ti target:(id)t selector:(SEL)s userInfo:(id)ui repeats:(BOOL)rep;
这和上面的初始化方法有什么区别么,接着发现者两个类方法和实例方法是要手动添加到NSRunLoop代码执行的:
[[NSRunLoop currentRunLoop]addTimer:timer forMode:NSDefaultRunLoopMode];
哈哈哈,这不就是我想要的东东嘛(ˇˍˇ),yo yo check now!
修改定时器的方法,手动添加NSRunLoop执行,然后网络请求不变。。。。OK,搞定。。
bi..bi.....bi....bi......
无压力了。。。。测试一个for循环1000次,没发生什么错误。。。好吧,来个总结。
一直都习惯用最上面的两个方法初始化定时器,然后fire,并且fire的作用只是把定时器的时间提前了,这个是之前使用的时候没有去考虑的。。这种东东在一个定时器下面不会有什么问题,但是多个定时器的话基本上就悲剧。。不过在同一个地方使用多个定时器这样的设计方法我暂时也不知道合理不合理,可能也会有意想不到的的错误,比如内存暴涨,性能受影响之类的,这个暂时没有去考虑,如果你有更好的解决方法,可以交流交流。
那些年我们踩过的坑-NSTimer的更多相关文章
- 那些年我们踩过的坑之表单reset
开发者往往是在一个又一个的坑中成长起来的,自学的开发者尤其如此,刚刚填完一个坑,转身又掉进另一个坑.有些坑很容易就跳出来了,也有些坑能整了一天都没头绪,第二天早上一来发现后面就有一架通往坑外的梯子,坑 ...
- 那些年我们踩过的坑,SQL 中的空值陷阱!
文章目录 NULL 即是空 三值逻辑 空值比较 NOT IN 与空值 函数与空值 DISTINCT.GROUP BY.UNION 与空值 ORDER BY 与空值 空值处理函数 字段约束与空值 SQL ...
- 项目中踩过的坑之-sessionStorage
总想写点什么,却不知道从何写起,那就从项目中踩过的坑开始吧,希望能给可能碰到相同问题的小伙伴一点帮助. 项目情景: 有一个id,要求通过当前网页打开一个新页面(不是当前页面),并把id传给打开的新页面 ...
- web开发实战--弹出式富文本编辑器的实现思路和踩过的坑
前言: 和弟弟合作, 一起整了个智慧屋的小web站点, 里面包含了很多经典的智力和推理题. 其实该站点从技术层面来分析的话, 也算一个信息发布站点. 因此在该网站的后台运营中, 富文本的编辑器显得尤为 ...
- "开发路上踩过的坑要一个个填起来————持续更新······(7月30日)"
欢迎转载,请注明出处! https://gii16.github.io/learnmore/2016/07/29/problem.html 踩过的坑及解决方案记录在此篇博文中! 个人理解,如有偏颇,欢 ...
- 【转载】Fragment 全解析(1):那些年踩过的坑
http://www.jianshu.com/p/d9143a92ad94 Fragment系列文章:1.Fragment全解析系列(一):那些年踩过的坑2.Fragment全解析系列(二):正确的使 ...
- Redis Cluster踩过的坑
Redis Cluster踩过的坑请参考如下链接:http://www.iteye.com/blogs/subjects/Redis_Cluster_Devops
- 第八篇:web之前端踩的一些坑
前端踩的一些坑 前端踩的一些坑 本节内容 事件代理 清除标签的所有事件 bootstrap的模态框自定义方法 ajax在django里面实现post提交 ajax提交数据嵌套 1.事件代理 之前写 ...
- 使用ffmpeg视频编码过程中踩的一个坑
今天说说使用ffmpeg在写视频编码程序中踩的一个坑,这个坑让我花了好多时间,回头想想,非常多时候一旦思维定势真的挺难突破的.以下是不对的编码结果: ...
随机推荐
- python string 对齐文本的几个方法
用rjust().ljust()和center()方法对齐文本
- C++——初识C++
1. C关键字 auto int double long char float short signed unsigned struct union enum static switch case d ...
- .NET Core 2.0.5安装具体步骤
.NET Core 2.0.5 comprises: .NET Core Runtime 2.0.5 .NET Core SDK 2.1.4 SDK Installer SDK Binaries ...
- SRM 739 Div.2
250 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostre ...
- DRF的@action装饰器
# 转自:http://www.cnblogs.com/zhzhlong/p/9325180.html 视图集中附加action的声明 from rest_framework.decorators i ...
- 7:django 中间件
中间件 中间件是一个连接django请求/相应处理的框架,是一个轻量级的低层次的全局影响django输入输出的系统插件. 每一个中间件组件负责一些特定的功能,这里我们我们只看一下如何激活使用系统自带的 ...
- hdu 1243(LCS变形)
反恐训练营 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submi ...
- lr手工添加关联函数的步骤:
点击“确定”后: 如何修改已经创建好的关联规则:
- Foxmail 登录 qq 账号时无法登录 提示我们设置了独立密码或使用授权码登录的解决方法
Foxmail 登录 qq 账号时无法登录 提示我们设置了独立密码或使用授权码登录的解决方法 1.首先我们设置我们邮箱的类型如下图所示 2.打开网页版的qq邮箱 在设置--->账户---&g ...
- sql 时间日期格式化
sql server2000中使用convert来取得datetime数据类型样式(全) 日期数据格式的处理,两个示例: CONVERT(varchar(16), 时间一, 20) 结果:2007-0 ...