iOS开发:block死循环及__weak弱引用提前释放的问题解决

本文深入探讨Block中出现死循环及对象提前释放的原因,解析内存溢出与弱引用问题,并提供解决方案,包括使用__weak和__strong关键字避免循环引用与提前释放。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、block中为什么会出现死循环?

问题:block中为什么会出现死循环?
原因: 内存溢出。
解决方法:使用__weak来解除block对对象的强引用。这样block中的对象是弱引用,使得两个都可以释放。
实例
1、当A对象里面强引用了B对象,B对象又强引用了A对象,这样两者的retainCount值一直都无法为0,于是内存始终无法释放,导致内存泄露。所谓的内存泄露就是本应该释放的对象,在其生命周期结束之后依旧存在。
2、这是2个对象之间的,相应的,这种循环还能存在于3,4……个对象之间,只要相互形成环,就会导致死循环的问题。
3、当然也存在自身引用自身的,当一个对象内部的一个obj,强引用的自身,也会导致循环引用的问题出现。常见的就是block里面引用的问题。

#define WeakSelf(type)  __weak typeof(type) weak##type = type;
People *p = [People new];
p.name = @"piter";
//弱引用
WeakSelf(p) 
p.MyBlock = ^(){
    NSLog(@"2.%@",weakp.name);
};
p.MyBlock();

2、block中为什么使用对象被提前释放?

那么这样就可以高枕无忧了吗?下面还有坑等着你:

后续问题:有些对象在还没开始使用就已经被释放。
原因: 弱引用对象本身,在还没有使用就已经被释放。
解决方法: 需要引入__strong来解决。
实例:在和GCD一起使用的时候中间就有个很大的坑,因为block中对对象是弱引用,在block中使用GCD的话,在GCD中使用的对象就是已经弱化的对象,所以会导致这个对象还没开始使用就已经被释放了。看下面例子

#define WeakSelf(type)  __weak typeof(type) weak##type = type;
#define StrongSelf(type)  __strong typeof(type) type = weak##type;
 
People *p = [People new];
	p.name = @"piter";
    WeakSelf(p) //弱引用
    p.MyBlock = ^(){
       dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
          NSLog(@"2.%@",weakp.name);
       });
};
   p.MyBlock();

这段代码,在block里面使用了GCD延迟调用,而在GCD代码块里面使用到了weakp这个对象,这个对象本身就是一个弱引用对象。在这里面没有使用就已经被释放了。所以像上面的代码是会输出null的。像这样的问题就需要引入__strong来解决。如下

People *p = [People new];
p.name = @"piter";
 //弱引用
WeakSelf(p);
p.MyBlock = ^(){
	StrongSelf(p)
	dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
		NSLog(@"2.%@,p.name);
	});
};
p.MyBlock();

这样就可以输出并且对象都会被释放。
总结: 这个strong是对block内部的强引用,不会干扰到block以外。所以不会影响people 和 myblock的释放。而对block内部的弱引用people强引用,就不会导致people提前释放了。
实例: 看AFNetworking也是使用weak加strong管理block内存的.

参考链接:
1、关于死循环 自己方法里面调用自己
2、__weak弱引用block造成提前释放的问题
3、深入研究Block用weakSelf、strongSelf、@weakify、@strongify解决循环引用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瓜子三百克

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值