Objective-C 内存管理

概述


Objective-C中没有垃圾回收机制,内存管理是依赖对象引用计数器来进行的。

每个对象内部都有一个与之对应的整数(retainCount)叫“引用计数器”,当一个对象在创建之后它的引用计数器为1,当调用这个对象的alloc、retain、new、copy方法之后引用计数器自动在原来的基础上加1。

通过dealloc方法来查看是否一个对象应经被回收,如果没有被回收则有可能造成内存泄露。

当一个对象被释放后,需要引用它的变量手动设置为nil,否则造成野指针错误(即被释放之后,再一次去访问,发现内存已经被回收,指针瞬间就没有归宿感,犹如离家的孩子,孤独无助),并且在给空对象发送消息是不会引起错误的。

野指针错误形式在Xcode中通常表现为:Thread 1:EXC_BAD_ACCESS(code=EXC_I386_GPFLT) pointer being freed was not allocated,表明指针已经被释放没有被分配,就是说你访问了一块已经不属于你的内存。

黄金法则


如果对一个对象进行了alloc、retain、copy操作,就获取了对应对象的所有权,那么就有义务对其进行release或着autorelease操作。简单来说就是需要遵循一个原则:谁创建,谁释放。

ARC环境下的内存管理


Block引起的循环引用


循环引用:self对block拥有一个强引用,而block内部又对self有一个强引用,形成闭环,发生内存泄露。

解决办法:在MRC中,block不会retain住对象的,但在ARC则会retain住,需要__weak来达到一个弱引用的效果。

- (void)performSelector:引起的内存泄露


运行原理:系统会自动将Object的引用计数+1,直到selector执行完毕后才会将引用计数-1。如果selector一直没用被执行的话,self就一直不能被释放,造成内存泄露。

解决方法:将未执行的perform取消,即[NSObject cancelPreviousPerformRequestWithTarget:self]。

NSTimer的问题


提出问题:NSTimer是用来在未来某个时刻执行一次或多次我们指定的方法,那么系统是如何保证timer出发action时,我们指定的方法是有效的,如果接收不到呢?

运行原理:系统会自动retain住接受者对象,直到我们指定的方法被执行。

解决办法:如果timer被要求执行一次我们指定的方法,系统会自动调用invalidated,而重复性的timer则不会自动调用,一般我们会在dealloc的时候,对timer调用invalidated方法,是timer失效,否则dealloc永远不会被调用,我们需要做的是在dealloc之前调用invalidated。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值