美文网首页
高效编写代码的方法(二十四):异常捕获中的内存管理

高效编写代码的方法(二十四):异常捕获中的内存管理

作者: 蜂猴 | 来源:发表于2016-10-09 21:16 被阅读41次

    Exceptions

    Exceptions(异常)在C++中和Objective-C中都有大量使用,并且异常对于两者都是兼容的,因此在C++中抛出的异常可以在Objective-C中进行处理,反之亦然。
    在OC中,对于特别重大的错误,我们会抛出一个异常;其他方面比如很多第三方库都会有这些异常处理,系统的库也会有异常抛出。

    Exceptions带来的内存问题

    当涉及到内存管理的时候,如果异常捕获代码写的不当,就会造成内存泄漏。
    比如以下这段代码:

        @try {
            SomeClass *object = [[SomeClass alloc] init];
            [object doSomethingMayThrow];
            [object release];
        } @catch (NSException *exception) {
            NSLog(@"出错啦!");
        }
    
    

    当一个对象在@try中的block中被retain了,而在该对象被release之前如果有异常抛出,比如上面那样,[object release]就根本不会执行,而直接跳转到@catch block。那么除非在@catch中妥善处理,否则该对象就泄漏了。而且万一这个泄露的对象是一个data管理类的对象,那么他所持有的对象都会一起泄露,后果非常严重。

    MRC中的解决办法

    将上面代码处理成这样就没问题了:

            SomeClass *object;
        @try {
            object = [[SomeClass alloc] init];
            [object doSomethingMayThrow];
        } @catch (NSException *exception) {
            NSLog(@"出错啦!");
        } @finally {
            [object release];
        }
    

    不过涉及到的对象或者异常捕获逻辑非常多,复杂的话,手动释放这些可能泄露的对象是非常乏味,而且容易遗漏。

    ARC

    在ARC中我们不能调用release方法,这时候该怎么处理这样的泄露情况呢?
    默认情况下,这时候ARC也不会帮我们处理内存泄露。但是我们可以在compiler flag中打开-fobj-arc-exception选项来帮助我们完善在exception中的内存管理。


    -fobj-arc-exception

    但是这样带来的后果就是在runtime会加入大量的管理对象的代码,用来监测并及时清除掉这些在exception中泄露的对象。后果就是增加打包体积。
    但是一般来说当异常被抛出的时候,我们的App也应该停止运行了,此时对象造成的泄露也会随着整个App的销毁而不存在,所以打开这个选项其实是不太符合使用规范的。

    其实以上这些知道就行,因为实际上也并不需要我们做过多的干预。

    相关文章

      网友评论

          本文标题:高效编写代码的方法(二十四):异常捕获中的内存管理

          本文链接:https://www.haomeiwen.com/subject/luxmyttx.html