iOS开发中,涉及到定时的问题,我们通常使用NSTimer来解决,例如下面的代码。

SFClass.h

#import <Foundation/Foundation.h>

@interface SFClass : NSObject

- (void)startPolling;
- (void)stopPolling;

@end

SFClass.m

#import "SFClass.h"

@implementation SFClass {
    NSTimer *_pollTimer;
}

- (void)dealloc {
    [_pollTimer invalidate];
}

- (void)stopPolling {
    [_pollTimer invalidate];
    _pollTimer = nil;
}

- (void)doSomething {

}

- (void)startPolling {
    _pollTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(doSomething) userInfo:nil repeats:YES];
}

@end

由于定时器会保留target对象,所以上面的代码会造成SFClass对象和NSTimer对象的相互引用,会导致内存泄漏问题。

我们可以通过下面的方式来解决。

NSTimer+SFBlocksSupport.h

#import <Foundation/Foundation.h>

@interface NSTimer (SFBlocksSupport)

+ (NSTimer *)sf_scheduleTimerWithTimeInterval:(NSTimeInterval)interval block:(void (^)(void))block repeats:(BOOL)repeats;

@end

NSTimer+SFBlocksSupport.m

#import "NSTimer+SFBlocksSupport.h"

@implementation NSTimer (SFBlocksSupport)

+ (NSTimer *)sf_scheduleTimerWithTimeInterval:(NSTimeInterval)interval block:(void (^)(void))block repeats:(BOOL)repeats {
    return [self scheduledTimerWithTimeInterval:interval target:self selector:@selector(sf_blockInvoke:) userInfo:[block copy] repeats:repeats];
}

+ (void)sf_blockInvoke:(NSTimer *)timer {
    void (^block)(void) = timer.userInfo;
    if (block) {
        block();
    }
}

@end

然后,我们使用定时器的代码就要修改为下面的样子

- (void)startPolling {
    _pollTimer = [NSTimer sf_scheduleTimerWithTimeInterval:1.0 block:^{
        [self doSomething];
    } repeats:YES];
}

仔细看看代码,发现依然有保留环,再修改一下:

- (void)startPolling {
    __weak typeof(self) weakSelf = self;
    _pollTimer = [NSTimer sf_scheduleTimerWithTimeInterval:1.0 block:^{
        SFClass *strongSelf = weakSelf;
        [strongSelf doSomething];
    } repeats:YES];
}

最终解决了相互引用的问题。

NSTimer的问题的更多相关文章

  1. Objective-C三种定时器CADisplayLink / NSTimer / GCD的使用

    OC中的三种定时器:CADisplayLink.NSTimer.GCD 我们先来看看CADiskplayLink, 点进头文件里面看看, 用注释来说明下 @interface CADisplayLin ...

  2. 解决NSTimer存在的内存泄漏的问题

    创建定时器会在一定的间隔后执行某些操作,一般大家会这样创建定时器,这样创建的定时,self对定时器有个引用,定时器对self也有个引用,造成了循环引用,最终造成了内存泄漏,如果定时器在做下载的操作就会 ...

  3. NSTimer

    NSTimer叫做“定时器”,它的作用如下 在指定的时间执行指定的任务 每隔一段时间执行指定的任务 调用下面的方法就会开启一个定时任务 + (NSTimer *)scheduledTimerWithT ...

  4. NSTimer整理总结

    对于定时器NSTimer,我们大家都不会陌生,在使用的时候,我们常常会遇到一些坑,例如:在Scrollview拖动时,timer会暂停:在子线程中如何创建一个定时器等.针对于一些我们所遇到的坑,我来总 ...

  5. ios - NSTimer中target的self是强引用问题

    当控制器ViewController跳转进入控制器OneViewController中的时候开启定时器,让定时器每隔一段时间打印一次,当OneViewController dismiss的时候,控制器 ...

  6. ios基础篇(二十三)—— 定时器NSTimer与图片的自动切换

    一.NSTimer NSTimer是一个能在从现在开始到后面的某一个时刻或者周期性的执行我们指定的方法的对象.可以按照一定的时间间隔,将制定的信息发送给目标对象.并更新某个对象的行为.你可以选择在未来 ...

  7. NSTimer “定时器”

    •NSTimer叫做“定时器”,它的作用如下 Ø在指定的时间执行指定的任务 Ø每隔一段时间执行指定的任务 Ø •调用下面的方法就会开启一个定时任务 + (NSTimer *)scheduledTime ...

  8. IOS OC 多任务定时器 NSRunLoop 管理 NSTimer

    下面有两种做法 1.使用日期组件 NSDateComponents 2.使用NSString 生成一个日期 //  创建一个日历对象 NSCalendar *calendar = [NSCalenda ...

  9. iOS NSTimer使用详解 开启、关闭、移除

    定时器定时器详解ios定时器关闭定时器NSTimer 一,要使用一个定时器首先要定义一个定时器: @property (strong, nonatomic) NSTimer *myTimer;//定时 ...

  10. NSTimer的使用[zhuang]

    NSTimer 的头文件 /* NSTimer.h Copyright (c) 1994-2015, Apple Inc. All rights reserved. */ #import <Fo ...

随机推荐

  1. ps中如何让图层在画布内水平居中

    下图每个小logo图案距离它们的上参考线的距离均为10px,而我们如何让图层在画布内水平居中??? 如上图中三个图层的图案是用来给Html/Css中的background属性使用的,虽然可以通过鼠标拖 ...

  2. 201521123047 j第五周学习总结

    1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 1.2 可选:使用常规方法总结其他上课内容. 参考资料: 百度脑图 XMind 2. 书面作业 1.代码阅读:Child压缩包 ...

  3. 201521123056 《Java程序设计》第14周学习总结

    1. 本周学习总结 2. 书面作业 1. MySQL数据库基本操作 建立数据库,将自己的姓名.学号作为一条记录插入.(截图,需出现自己的学号.姓名) 在自己建立的数据库上执行常见SQL语句(截图) 参 ...

  4. 201521123056 《Java程序设计》第12周学习总结

    1. 本周学习总结 2. 书面作业 将Student对象(属性:int id, String name,int age,double grade)写入文件student.data.从文件读出显示. 1 ...

  5. 201521123090《Java程序设计》第10周学习总结

    本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 书面作业 本次PTA作业题集异常.多线程 finally 题目4-2 1.1 截图你的提交结果(出现学号) 1.2 ...

  6. lintcode.68 二叉树后序遍历

    二叉树的后序遍历    描述 笔记 数据 评测 给出一棵二叉树,返回其节点值的后序遍历. 您在真实的面试中是否遇到过这个题? Yes 样例 给出一棵二叉树 {1,#,2,3}, 1 \ 2 / 3 返 ...

  7. Could not instantiate bean class [org.springframework.web.multipart.MultipartFile]: Specified class

    如果在使用SpringMVC中使用文件上传的MultipartFile对象时,出现了以下的错误: Could not instantiate bean class [org.springframewo ...

  8. Ubuntu Server 12.04安装图解教程

                                                                                                Ubuntu S ...

  9. JVM菜鸟进阶高手之路三

    转载请注明原创出处,谢谢! 笨神大大分享: 小程序里面搜索:JVMPocket,这个小程序是笨神大大提供的,里面可以搜索相关JVM参数,用法. -XX:MaxTenuringThreshold,这个参 ...

  10. 为异常处理做准备,熟悉一下WinDbg工具

    为异常处理做准备,熟悉一下WinDbg工具 马上开始异常处理第二讲,但是在讲解之前,还有熟悉一下我们的WinDbg工具,当然你如果熟悉这个工具,那么就可以不用看了. 一丶熟悉WinDbg界面 刚开始打 ...