异常和异常所带来的内存管理问题

异常的捕捉

 
 
  1. // @try 块捕捉异常
  2. @try {
  3. // 这里发生了一个异常
  4. @throw [NSException exceptionWithName:@"demo" reason:@"the exception demo" userInfo:nil] ;
  5. }
  6. @catch (NSException *exception) {
  7. // 输出异常详细原因
  8. NSLog([exception reason]);
  9. // 输出异常名称
  10. NSLog([exception name]) ;
  11. // @throw ; // 再次将异常抛出,@catch 块中@throw 未指定欲抛出的异常指针则默认抛出@catch 的参数.
  12. }
  13. @catch(id exception){
  14. // 处理其他异常
  15. }
  16. @finally {
  17. }

@catch 块中抛出异常,若@throw 未指定欲抛出的异常指针则默认抛出@catch 的参数. 上处代码的catch块则会抛出 exception

异常所带来的内存管理问题

 
 
  1. //不捕获异常的内存管理
  2. Person *p = [[Person alloc] init];
  3. [p description] ;
  4. [p release] ;
  5. // 捕获异常的内存管理
  6. Person *p2 = [[Person alloc] init ] ;
  7. @try {
  8. [p2 description] ;
  9. }
  10. @catch (NSException *exception) {
  11. NSLog(@"exception : %@" ,[exception reason]) ;
  12. }
  13. @finally {
  14. [p2 release];
  15. }

异常和自动释放池

异常处理有时候会遇到异常对象被自动释放的小问题,因为你不知道什么时候释放异常对象,所以它总是作为自动释放对象而创建。当自动释放池销毁的时候,自动释放池中托管的所有对象也会被销毁,其中包括异常对象。
观察如下代码。

 
 
  1. -(void) test{
  2. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init ];
  3. @try {
  4. // 此处会发生异常
  5. NSDictionary *myDictionary = [[NSDictionary alloc] initWithObjectsAndKeys:@"asdasd", nil];
  6. }
  7. @catch (NSException *exception) {
  8. // @throw 会在finally 之后执行,这个时候 exception 已经被release。
  9. @throw ;
  10. }
  11. @finally {
  12. [pool release] ;
  13. }
  14. }

上述代码看似正确,但别高兴的太早,@catch代码块中再次抛出异常,而@fianlly 则会在@throw 之前执行,这样会导致pool被释放,而在pool中托管着异常对象,则异常对象exception也会被释放。在外部使用这个exception的时候就会发生异常。

解决办法: 在pool外部保留

 
 
  1. -(void) test{
  2. // 用于保存exception
  3. id saveException = nil ;
  4. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init ];
  5. @try {
  6. // 此处会发生异常
  7. NSDictionary *myDictionary = [[NSDictionary alloc] initWithObjectsAndKeys:@"asdasd", nil];
  8. }
  9. @catch (NSException *exception) {
  10. // retain 一下再throw 确保对象不会被释放
  11. saveException = [exception retain];
  12. @throw ;
  13. }
  14. @finally {
  15. [pool release] ;
  16. // 保留下来的exception 也需要释放,当外部pool release的时候才会被释放
  17. [saveException autorelease ];
  18. }
  19. }

XCode禁用异常。

选择项目的属性文件 --》 搜索Exception --> Enable Objective-C Exceptions --> 选择NO
112224589495123.png

转载于:https://www.cnblogs.com/mrwu/p/4331142.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值