nsarray 释放_记一下:NSArray强引用、弱引用

在iOS的本地通知功能中,有个细节。

一般使用通知功能NSNotification,都需要添加和移除观察者,否则会引起一些问题:

在iOS9以下,如果观察者已经被释放,但是没有移除出通知中心,那么当这个通知发出时,会引起野指针崩溃,iOS9以上对这个问题做了优化,没有手动移除的话,也不会发生什么,估计苹果也认为自动释放会显得智能一点。

关于iOS如何做到在观察者dealloc的时候,自动移除观察者,网上也有现成的案,这里只是通过这个事情联想到,数组强引用的问题。

Foundation中数组在元素被添加的时候(这里的数组指平常使用的NSArray和NSMutableArray)会强引用持有,就算使用__weak修饰也没有用,导致一些奇特的内存泄漏和循环引用问题。

那么除了业务注意的话,就是要找到一些若引用集合Weak Reference Collection的实现方法了.

方法0:使用弱引用包装

NSValue *value1 = [NSValue valueWithNonretainedObject:_obj1];

[_array addObject:value1];

NSValue可以对某对象弱音引用的方法,我们再将value保存到数组中就可以了。

但是不建议使用NSValue,可以使用自定义的类来实现,因为valueWithNonretainedObject并不会判空,同时,释放掉的对象,也不会将引用置为空,导致野指针问题。

方法1:使用CoreFoundation

使用CoreFoundation中的CFArrayCreateMutable,可以实现弱引用数组。

但是需要小心内存释放问题,同时还要注意类型准换。

所以不建议使用此方法。

方法2:使用NSPointerArray

NSPointerArray可以很好的解决数据类型和自动置空的问题

NSPointerArray提供strongObjectsPointerArray和weakObjectsPointerArray工厂,weakObjectsPointerArray就是我们需要的弱引用数组方法。

NSPointerArray也处理了元素释放导致数组元素个数不稳定的问题:添加了allObjects属性,代表所有未释放的对象,而原本的count则表示所有元素个数。

_storage = [NSPointerArray weakObjectsPointerArray];

[_storage addPointer:(__bridge void *)(obj)];

[_storage pointerAtIndex:0]; //obj 此处返回的是对象指针,如果对象已经释放,则为nil.

方法3:使用NSHashTable和NSMapTable

NSHashTable和NSMapTable使用思路类似NSPointerArray,同时也有实现弱引用的工厂方法,用来满足弱引用的需求。

二者同NSPointerArray区别在于NSHashTable可以看成NSSet,NSMapTable可以看成NSDictionary。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值