NSTimer作为一个经常使用的类,却有一个最大的弊病,就是会强引用target。造成调用timer很麻烦。稍有不慎就造成内存泄漏。

下面就是为解决问题做的封装。

直接上代码:

#import <Foundation/Foundation.h>

@interface LZLTimer :
NSObject

-(void)startTimerInterval:(NSTimeInterval)ti target:aTarget selector:(SEL)selector
userInfo:(id)userInfo repeats:(BOOL)yesOrNo;

@end

#import "LZLTimer.h"

@interface LZLWeakTimerTarget :
NSObject

@property (nonatomic,weak)
id target;

@property (nonatomic,assign)
SEL selector;

- (void)timerDidFire:(NSTimer *)timer;

@end

@implementation LZLWeakTimerTarget

- (void)timerDidFire:(NSTimer *)timer {

if(_target) {

//消除arc警告

IMP imp = [_target
methodForSelector:_selector];

if ([NSStringFromSelector(_selector)
hasSuffix:@":"]) {

void (*func)(id,
SEL, id) = (void *)imp;

func(_target,
_selector, timer);

}else {

void (*func)(id,
SEL) = (void *)imp;

func(_target,
_selector);

}

} else {

[timer invalidate];

}

}

@end

@interface LZLTimer () {

NSTimer *_timer;

}

@end

@implementation LZLTimer

-(void)dealloc {

if (_timer!=nil) {

[_timer
invalidate];

_timer =
nil;

}

}

-(void)startTimerInterval:(NSTimeInterval)ti target:aTarget selector:(SEL)selector
userInfo:(id)userInfo repeats:(BOOL)yesOrNo {

if (nil ==
_timer) {

WMWeakTimerTarget *weakTarget = [[WMWeakTimerTarget
alloc] init];

weakTarget.target = aTarget;

weakTarget.selector = selector;

_timer = [NSTimer
scheduledTimerWithTimeInterval:ti
target:weakTarget selector:@selector(timerDidFire:)
userInfo:userInfo repeats:yesOrNo];

}

}

@end

NSTimer解除循环引用的更多相关文章

  1. iOS 里面 NSTimer 防止 循环引用

    使用NSTimer的类 #import "TBTimerTestObject.h" #import "TBWeakTimerTarget.h" @interfa ...

  2. NSTimer的循环引用

    在日常开发中想到会引起循环引用的一般比较容易想起的是 1.delegate 2.block 今天要说的就是另外一个,NSTimer 这个比较容易会被忽略掉 简单的说就是创建timer为成员变量的时候t ...

  3. CADisplayLink、NSTimer循环引用解决方案

    前言:CADisplayLink.NSTimer 循环引用问题 ​ CADisplayLink.NSTimer会对Target产生强引用,如果target又对他们产生强引用,那么就会引发循环引用. @ ...

  4. iOS 循环引用解决方案

    一.BLOCK 循环引用 一般表现为,某个类将block作为自己的属性变量,然后该类在block的方法体里面又使用了该类本身.构成循环引用. // 定义 block 的时候,会对外部变量做一次 cop ...

  5. 使用gc、objgraph干掉python内存泄露与循环引用!

    Python使用引用计数和垃圾回收来做内存管理,前面也写过一遍文章<Python内存优化>,介绍了在python中,如何profile内存使用情况,并做出相应的优化.本文介绍两个更致命的问 ...

  6. iOS 循环引用讲解(中)

    谈到循环引用,可能是delegate为啥非得用weak修饰,可能是block为啥要被特殊对待,你也可能仅仅想到了一个weakSelf,因为它能解决99%的关于循环引用的事情.下面我以个人的理解谈谈循环 ...

  7. ios block常见的错误(二)——循环引用

    这篇博文继续block的常见错误——循环引用. 循环引用是很多初学者不能察觉的,其产生的原因,是block中的代码会对对象进行强引用. 读者请阅读示例代码1,并思考示例代码1所创建的对象能否被正常销毁 ...

  8. 浅谈 关于ARC循环引用得问题

    这段时间在研究关于ARC得循环引用导致变量不能释放,在此先介绍一本书英文书: <Pro Multithreading and Memory Management for iOS and OS X ...

  9. iOS循环引用

    iOS循环引用 当前类的闭包/Block属性,用到了当前类,就会造成循环引用 此闭包/Block应该是当前类的属性,我们经常对Block进行copy,copy到堆中,以便后用. 单方向引用是不会产生循 ...

随机推荐

  1. vuejs 基础总结(one)

    vuejs 入门知识点 1.active-class 是哪个组件的属性?嵌套路由怎么定义 (1).active-class 是 vue-router 模块的 router-link 组件的属性 (2) ...

  2. android startservice无法启动服务

    1.android startservice无法启动服务 之前MainActivity.java中启动service源代码如下: private void startMyService() { //启 ...

  3. ASP.NET-MVC中Entity和Model之间的关系

    Entity 与 Model之间的关系图 ViewModel类是MVC中与浏览器交互的,Entity是后台与数据库交互的,这两者可以在MVC中的model类中转换 MVC基础框架 来自为知笔记(Wiz ...

  4. Android中Handler原理

    Handler主要是主线程和子线程通信.一般子线程中做一些耗时操作做完之后通知主线程来改动UI. 实际上android系统在Activity启动或者状态变化等都是通过Handler机制实现的. 首先进 ...

  5. node16---cookie session

    03.js var express = require("express"); var app = express(); var db = require("./mode ...

  6. vue中的swiper element ui

    欢迎加入前端交流群交流知识&&获取视频资料:749539640 很多同学问,怎么把swiper引入到vue的脚手架里去,之前的一篇博客有提到怎么引入,但是后来感觉不怎么好,还是用一些v ...

  7. 3.多线程传参,以及tuple数组

    #include <Windows.h> #include <thread> #include <iostream> #include <tuple> ...

  8. Python之Linux下的virtualenv

    在使用 Python 开发的过程中,工程一多,难免会碰到不同的工程依赖不同版本的库的问题: 亦或者是在开发过程中不想让物理环境里充斥各种各样的库,引发未来的依赖灾难. 此时,我们需要对于不同的工程使用 ...

  9. POJ 3368 线段树

    思路: 先统计在第i个位置当前数字已经出现的次数. 维护两个数组,一个是当前位置的数字最后一次出现的位置,另一个是当前位置的数字第一次出现的位置 查找的时候分为两种情况: 没有和边界相交(意会意会)的 ...

  10. MySQL日期数据类型和时间类型使用总结

    转自: http://blog.chinaunix.net/space.php?uid=11327712&do=blog&id=32416 MySQL 日期类型:日期格式.所占存储空间 ...