码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-03-11 23:24:35      阅读:209      评论:0      收藏:0      [点我收藏+]

标签:

异常的捕捉

    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
技术分享

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

标签:

原文地址:http://www.cnblogs.com/mrwu/p/4331142.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!