nstimer循环引用_ios开发中经典循环引用场景?

1、属性传值循环引用

如:- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

TabelViewCell *cell = ...

cell.tableView = tableView;

return cell;

}

@interface TableViewCell: UITableViewCell

@property (nonatomic, strong) UITableView *tableView;

@end

cell 添加到tableView上被tanleView强引用,cell中tableView被强引用,造成循环引用;

所以cell中tableView应该用weak关键字

2、delegate属性用strong关键字循环引用

定义:

@interface Class A: NSObject

@property (nonatomic, strong) BView *someView;

@property (nonatomic, strong) XXXDelegate delegate;

调用:

self.someView.delegate = self;

class A强引用BView, BView的代理指向A,因为delegate是strong关键字修饰,所以BView会强引用A的实例,造成循环引用

所以delegate关键字应该用weak修饰

3、block接获变量,循环引用

self.block = ^{

self.someProperty = xxx;

}

self持有block,block截获self(这一点我也没搞太明白),赋值会把block copy到堆上,持有相关变量,就是self持有block,block又持有self,形成循环引用

解决方式:

__weak typeOf(self) weakSelf = self;

self.block = ^{

weakSelf.someProperty = xxx;

}

延展:

但这种方式可能会造成内存提前回收,比如说:block中不是简单的赋值操作,而是一个耗时的网络请求,block中的操作还没有结束,self被释放掉了,这个时候seakSelf为nil,所以someProperty无法赋值

解决方式:

__weak typeOf(self) weakSelf = self;

self.block = ^{

__strong typeOf(self) strongSelf = weakSelf;

strongSelf.someProperty = xxx;

}

原理: block中强引用self,所以self在要被释放时检查到引用计数不为0,所以系统无法释放self实例,只有等待block执行完毕,block内存被释放的时候,才会释放掉self,所以someProperty赋值成功

4、NSTimer循环引用

例如:

class ViewController

@property (nonatomic, strong) NSTimer *timer;

调用:

self.timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(timerRun) userInfo:nil repeats:YES];

这个类似于delegate,把timer的target指向了self,所以可以用weak的方式解除循环引用;

但是在实际的代码使用过程中,timer一般需要加入到runloop中,被runloop强引用,所以timer强引用viewController, runloop强引用timer,ViewController pop后无法释放,具体可以查看这篇博客对NSTimer的分析

所以可以采用另一种方式解决循环引用:

__weak typeof(self) weakSelf = self;

self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {

[weakSelf timerRun];

}];

注意:timer释放前需要invalidate

总结:iOS中常见的循环引用大致有这4种,根据实际的情况分析解决办法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值