温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

iOS优化内存,提升性能 之五

发布时间:2020-07-30 18:45:52 来源:网络 阅读:1021 作者:iKingLai 栏目:移动开发

Advanced Autorelease Pool 高级自动释放池


在之前的章节你已经学习了很多基本的内存方面的知识。这个部分将会涉及到使用自动释放的高级技术,同时展示你应该在哪里使用,从而在受限的情况下获得比较高的性能。


在每一个线程中,你应该要有一个自动释放池来收集和存储所有自动释放的对象。如果在每一个线程中,没有自动释放池的话,所有的autoreleased对象会泄露,你将会有一个重大的内存泄露。自动释放池是通过栈的形式组织在一起的;下面部分会解释。


自动释放池和栈


自动释放池存储在一个栈中,通常被理解成嵌套的。无论何时你创建一个新的自动释放池,它都会被push到栈的顶部。然后所有新的autoreleased对象会被push到这个新的自动释放池中。


通过下面的代码你可以看到,对象(比如myArray和myString)内部的方法doSomething将会存储在myPool中,而不是应用的main pool中:


- (void)doSomething {

   @autoreleasepool {

           NSArray *myArray = [NSArray array];

           NSString *myString = [NSString string];

     }

}


这是main方法的main pool:


int main(int argc, char *argv[]){

   @autoreleasepool {
           int retVal = UIApplicationMain(argc, argv, nil, nil);

     }

   return retVal;

}


@autoreleasepool块结束的时候,当时间生命周期结束时,所有存储在这个pool中的autoreleased对象jiang将被released。


图7-9展示了这个概念。对于一个好的性能来说,这是一个非常重要的概念 --  知道尽可能快的release对象。


iOS优化内存,提升性能 之五


自动释放池和线程


当创建一个新的线程时,你需要创建一个新的自动释放池对象,然后将这个pool和新的线程联系在一起。因此当线程停止时,你的自动释放池会deallocated,所有的autoreleased对象也会deallocated。第6章我会深入的讨论这个主题,所以你应该复习一下,如果你在理解概念时需要一些帮助的话。


自动释放池对性能的影响


旧的内存管理规则依然能够应用在用ARC编写的代码上,如果你没有使用new,alloc和copy调用一个方法,这个对象就已经是autoreleased了。如果你在一个循环中创建了很多的autoreleased对象,很快内存就会耗尽。


这个代码演示了在循环中处理内存管理最好的方法:


- (void)doSomethingWithAutoRelease {

       for (int i = 0; i < 1000; i++) {

               @autoreleasepool {
                Product *product = [Product productWithItemID:@""];

                // process and display the product here

               }

       }

}


在循环结束的时候,以及在@autoreleasepool块的尾部,所有的autoreleased对象会released。这种方法你能够控制和release所有位使用的对象和回收你的内存。



Instruments


当我讨论使用设备和模拟器测试的时候,第2章已经介绍过Instruments。在这个部分,我将简短的讨论一些更加更高级的问题,这些问题会影响到你应该选择什么样的内存管理方式。


大部分时间,你需要使用到4中主要的instruments。

  • Static Analyzer

  • Leaks Instruments

  • Zombie

  • Object allocation



Static Analyzer


static Analyzer是一个比较快速的方法检查一些微小的比较明显的内存泄露。例如,如果你alloc了一个新的对象,没有在方法内release它,如图7-10所示,Static Analyzer能够快速的发现。


iOS优化内存,提升性能 之五


Leak Instrument


Leaks Instrument更加复杂,它需要时间允许和分析,但是会给出更好的结果。在运行过程中,它能够检测到所有数据轨迹的内存泄露。


iOS优化内存,提升性能 之五


Leaks Instrument能给出内存泄露对象更多的细节信息,如图7-11.


iOS优化内存,提升性能 之五

同样能够显示泄露确切的发生在哪一行(图 7-12)。


Zombie


Zombie能够帮助你检查EXEC_BAD_ACCESS导致的应用程序崩溃的问题。这是非常有帮助的,如果你的应用老是崩溃,但是通过日志或检查代码又发现不了问题的话。


如图7-13,Zombie会显示给你一个actions的list,包括malloc,autorelease,retain,和release,当应用崩溃的时候。你使用Zombie跟踪autorelease和release方法。


iOS优化内存,提升性能 之五


Object Allocation


Object allocation是我要介绍的内存相关的最后一个工具。它显示了运行过程中,所有内存的使用情况。这个工具是非常有用的,当内存使用增长很多,你需要跟踪使用内存较多的那些代码。


iOS优化内存,提升性能 之五

图7-14显示了代码所在行,对象创建的时间,和创建对象的调用者。


Memory Waring Levels


最后我要讨论的是关于内存警告。当你的内存增长到一定点时,iOS系统会尝试告诉你,通过在view controller中调用didReceiveWarning方法。你应该在这个方法中释放一些内存。



注意:在你的应用中还有其他方法收到内存警告:applocation delegate收到内存警告,然后在其他对象中调用相应的方法,或者你的对象通过NSNotification注册了接受内存警告的通知。



内存警告的第1级别是最重要的:它意味着你的代码已经快速的使用了很多内存。否则,你的app将会收到第2个级别的警告,然后会崩溃。


总结


内存对你的app的性能有重要影响。如果你不恰当的使用会导致你的app崩溃。在本章,你学到了在objective-c中很多关于内存管理方面的重要概念,这能够帮助你避免内存泄露和应用程序崩溃。UIViewController的生命周期同样非常重要,因为它和内存的管理和控制有关。它同样会影响到应用的性能和体验。最后,你学到了当在处理内存时,autorelease和release的不同,以及何时应该用其中的一个替代另外一个。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI