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. (2)ES6解构赋值-数组篇

    1.解构赋值-数组篇 //Destrcturing(解构) //ES5 /* var a = 1; var b = 2; var c = 3; */ //ES6 var [a,b,c] = [1,2, ...

  2. MySQL (九)-- 代码执行结构、函数、存储过程

    1 代码执行结构 代码执行结构有三种:顺序结构.分支结构和循环结构. 1.1 分支结构 分支结构:实现准备多个代码块,按照条件选择性执行某段代码. 在MySQL中只有if分支. 基本语法 if 条件判 ...

  3. 201521123090 《Java程序设计》 第8周学习总结

    本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 1.2 选做:收集你认为有用的代码片段 书面作业 本次作业题集集合 List中指定元素的删除(题目4-1) 1.1 ...

  4. 201521123098 《Java程序设计》第6周学习总结

    1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 注1:关键词与内容不求多,但概念之间的联系要清晰,内容覆盖 ...

  5. 201521123011《Java程序设计》第6周学习总结

    1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. XMind 2. 书面作业 1.clone方法 1.1 O ...

  6. 201521123055 《Java程序设计》第5周学习总结

    1. 本章学习总结 2. 书面作业 Q1.代码阅读:Child压缩包内源代码 1.1 com.parent包中Child.java文件能否编译通过?哪句会出现错误?试改正该错误.并分析输出结果. 1. ...

  7. 201521123070 《JAVA程序设计》第13周学习总结

    1. 本章学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 Q1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jm ...

  8. 解决vsftp无法启动问题(转)

    [root@node11 ~]# service vsftpd restartShutting down vsftpd:                                      [F ...

  9. 《Head First Java》读书笔记(3) - 异常和IO

    1.异常处理 我们在调用某个方法时,会被编译器告知需要捕捉异常和处理,意味着你调用的这个方法是有风险的,可能会在运行期间出状况,你必须写出在发生状况时加以处理的代码,未雨绸缪!这就是Java中异常处理 ...

  10. python 接口测试1 --如何创建和打印日志文件

    python自带的logging实在是不好用,推荐使用logbook 思路如下: 1.创建path.py文件,获取工程根路径 2.创建log.py文件,在工程根路径下创建日志文件(文件名称按日期命名) ...