Effective Objective-C 2.0 读书笔记——内存管理(下)

Effective Objective-C 2.0 读书笔记——内存管理(下)

在 dealloc 方法中只释放引用并解除监听

对象在经历其生命期后 ,最终会为系统所回收 ,这时就要执行dealloc 方法了。 在每个对象的生命期内,此方法仅执行一次,也就是当保留计数降为0的时候。在这个方法之中,主要就是释放对象所拥有的引用。

比如CoreFoundation 对象就必须手工释放,因为它们是由纯C的API 所生成的。 在dealloc方法中,通常还要做一件事,那就是把原来配置过的观测行为(observation behavior) 都清理掉。之前讲到通知传值就有说到,我们当不需要监听后就需要在dealloc函数当中将注册的通知中心进行销注。

系统不保证每个对象的 dealloc 都会在预定时机调用,特别是在应用终止时可能仍有对象存活,而操作系统会在程序退出后回收所有资源。对于那些开销较大或系统内稀缺的资源(例如文件描述符、套接字等),最好在对象不再需要时主动调用专门的“清理方法”(如 close),而不是等到 dealloc 时才释放。

以下是书中给出的例子:

-(void) close{
   
   
	//关闭资源
	_close = YES;

}

-(void)dealloc {
   
   
	if(!_close) {
   
   
		NSLog(@"数据库没有在dealloc之前关闭!!!");
  	[self close];
  }

}

有时候我们不只是想输出一条错误的消息,可能需要我们抛出对应的异常来表明我们这是一个严重的错误。

调用 dealloc 后,对象已经不再有效,任何进一步调用属性存取方法或其他业务逻辑的方法都可能导致错误。
为此,开发者应确保在 dealloc 中不调用那些可能依赖对象正常状态的操作。

编写 “异常安全代码” 时留意内存管理问题这一章节

在之前我们学习了书中关于如何抛出异常的方法,即使用@try…@catch…@finally或者NSError。这一章节主要讲了使用@try…@catch…@finally在MRC的情况下需要注意的一些点。

当发生异常时,内存管理需要特别关注,否则可能会导致内存泄漏。书中的这一段话强调了以下关键点:

  1. 异常可能导致对象泄漏
    try 代码块中,如果先对某个对象进行了 retainalloc 操作(增加了引用计数),但在释放它之前抛出了异常,而 catch 代码块未能正确处理该问题,那么该对象的内存将不会被释放,从而导致内存泄漏。
  2. C++ 对象的析构函数由 Objective-C 的异常处理机制执行
    在 C++ 中,每个对象都有一个析构函数(destructor),用于在对象生命周期结束时执行清理操作。而 Objective-C 的异常处理机制会确保异常发生时,C++ 对象的析构函数能够正确执行,以防止 C++ 对象在异常发生时泄漏。
  3. 系统资源(如文件句柄)更容易泄漏
    C++ 对象由于析构函数的存在,能在异常发生时得到一定程度的保护,但文件句柄、网络连接等系统资源没有自动管理机制。如果异常发生后没有手动清理这些资源,就会造成更严重的资源泄漏。因此,在处理这类资源时,应当使用 @try ... @finally 结构来保证清理操作一定会执行。
@try {
   
   
    EOCSomeClass *object = [[EOCSomeClass alloc] init];
    [object doSomethingThatMayThrow];
    [object release];
}
@catch (NSException *exception) {
   
   
    NSLog(@"Whoops, there was an error. Oh well...");
}

不难看出如果在执行doSomethingThatMayThrow如果抛出异常,那么就没有办法对obj进行release,那我们可以对代码进行修改

EOCSomeClass *object = [[EOCSomeClass alloc] init];
@try {
   
   
    [object doSomethingThatMayThrow];
}
@catch (NSException *exception) {
   
   
    NSLog(@"Whoops, there was an error. Oh well...");
}
@finally {
   
   
    [object release];
}

样可以保证无论是否发生异常,对象都能最终被释放,从而避免内存泄漏。

这里书中也介绍了一个“objc-arc-exceptions”这个编译器参数。ARC 主要依赖编译器自动生成内存管理代码,默认假定代码中不会使用异常。这样可以

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值