内存管理(4) - 循环引用

本文详细探讨了iOS开发中的循环引用问题,包括循环引用的定义、发生场景,如block、delegate和NSTimer。分析了如何在block中避免循环引用,并提出了使用weak或__weak修饰符、调整引用关系等解决方案。最后提到了在delegate和NSTimer使用中防止内存泄露的方法。
摘要由CSDN通过智能技术生成

当用指针指向某个对象时候,可以对其进行管理(通过retain和release)就拥有对这个对象的强引用或弱引用


1、什么是循环引用?

这里写图片描述

结论:

  • 当两个对象相互持有对方(即拥有对对方的强引用),此时各自的引用计数都为1,释放不了,而造成内存泄露。

  • 当多个对象能形成一个环时候情况类似。

  • 用weak或者__weak创建归零弱引用
    这里写图片描述

因为c指向的地方被释放了,调用它可能会导致问题,如果是weak或者__weak创建的:
这里写图片描述


2、循环引用发生在什么地方?

相关类之间

如:假如view持有subView时,而subView中有属性为strong修饰的view(会发生循环引用)

这里写图片描述

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    TestCell *cell =[tableView dequeueReusableCellWithIdentifier:@"UITableViewCellIden" forIndexPath:indexPath];

    cell.tableView = tableView;
    //这里如果上图属性为strong的话,那么会导致循环引用
    return cell;
}

原因分析:

UITableView 是持有 UITableViewcell(引用计数值为1)的,而TestCell继承自UITableViewcell可以看做一个UITableViewcell类型,它对它的类的实例变量(指针,都在堆中)也是持有的,所以属性用strong修饰,那么属性将会对指向的对象持有。如果此时刚好这个对象是UITableView类型,那么就发生了循环引用。

这里写图片描述


2、易发生在block

如:

//.h文件在ARC
typedef void(^block)(void);

@interface Test : NSObject

@property (nonatomic, copy)block testBlock;
@property (nonatomic, assign)NSInteger temp;
@property (nonatomic, copy)NSString* str;

- (void)inmethod1;

@end
//mian文件在MRC,为了能手动release观察是否发生循环引用。
int main(int argc, char * argv[]) 
{
    Test *test = [[Test alloc]init];

    [test inmethod1];
    [test release];

    NSLog(@"程序即将结束");
}

1、在ARC中(.m文件在ARC中来即测试在ARC中block的影响而导致的循环引用)

这里写图片描述

分析 :可以看到没有调用dealloc,说明出现了循环引用,那么循环引用怎么产生的呢。

  • self 持有 _textblock , _textblock因为通过点方法(setter方法)把inmethod1中的stackblock作copy到了堆上变成了mallocblock,所以_textblock持有mallocblock(修饰符为copy),而在mallocblock中使用了self有关的系列(堆会对self持有)。所以发生了循环引用。

这里写图片描述

又如果是这样:
这里写图片描述

分析 :可以看到没有调用dealloc,说明出现了循环引用,那么循环引用怎么产生的呢?而且我们也没有调用setter方法(即没有用到copy修饰的作用)。

  • 可以看到这里直接对testBlock进行操作,首先因为self持有_testBlock,而后的block进行了 = 操作ÿ
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值