温馨提示×

温馨提示×

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

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

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

发布时间:2020-07-30 08:57:14 来源:网络 阅读:621 作者:iKingLai 栏目:移动开发

在本章,你将学到:

  • 复习旧的手工内存管理的策略

  • 对象所有权策略

  • 基于旧的手工内存管理之上的新的自动内存管理

  • 什么是对象的拷贝以及如何使用它

  • 如何恰当的使用autorelease和release方法

  • 复习内存测量


iPhone是一个内存有限的环境。但是,很多开发者要么低估了它,要么高估了它,因此并没有利用好iPhone上的可用内存来提升性能。还有一些开发者非常担心iPhone上的内存和性能,以至于他们过度优化,这样其实对代码的可阅读性是非常有害的,也使得日后的维护变得更加困难。


为了有效利用内存来提升性能,同时使代码更容易阅读,又不让应用崩溃,你需要理解iPhone环境下的内存结构。你需要学习如何避免在内存在中过多引用对象,它能够导致内存警告和程序崩溃。你同样需要知道何时retain或release一个对象;如果在内存中的对象太少,可能会使得你的计算变得缓慢,因为你需要重新构造对象或从文件系统中加载。


简单的回顾


本部分是学习新的自动引用计数(ARC)的一个很好的过渡。有些人可能对于转到新的课程会有些迷惑。我希望本部分能够帮助你非常顺利的过渡到新的ARC机制上。


旧的对象所有权策略


如果A对象有B对象的一个强引用,那么A对象需要手动的release对象B,这是旧的概念。如果A对象alloc,copy,mutableCopy,new或retain对象B,那么A对象就有了对象B的强引用。另一方面,如果A对象没有使用这些方法,那么A对象拥有B对象的弱引用。


对于旧的内存管理机制,如果你的对象或方法有另一个对象B的强引用,你有责任release或autorelease对象B。每一个B对象的强引用都会使得它的引用计数加1。如果没有任何对象拥有B对象的强引用,换句话说,B对象的引用计算为0,B对象就会被deallocated(Listing 7.1)。


Listing 7.1. Release the Object if You Have a Strong Reference

- (void)doSomething {
       NSObject *obj = [[NSObject alloc] init];

       NSLog(@"obj: %@", obj);
       [obj release];

}



AutoRelease


autorelease方法会将对象发送到一个池中,然后声明这个对象稍后将要被release掉。使用这个方法,你不想拥有任何对象的强引用,但是你也不想它被dellocated。请查看Listing 7.2 。


Listing 7.2. Memory Issue

  • -  (NSObject *)getObj {
           NSObject *obj = [[NSObject alloc] init];

  •        return obj;

    }

  • -  (void)anotherMethod {
           NSObject *myObj = [self getObj];
           // do something
           // Should I release the object here?

  •       [myObj release];

    }


现在,在你使用完一个对象后,你要问问自己是否需要release它。通常,你可能会认为要release它;否则,没人release它,那么就会发生内存泄露。但是,因为你的anotherMethod方法没有myObj的强引用,你不能release myObj。唯一的办法就是像Listing 7.3 使用autorelease。


Listing 7.3. Use Autorelease to Solve the Problem

  • -  (NSObject *)getObj {
       NSObject *obj = [[NSObject alloc] init];

  •    return [obj autorelease];

    }

  • -  (void)anotherMethod {
       NSObject *myObj = [self getObj];

  •    // do something

    }



注意:anotherMethod没有其他对象的强引用。



Autorelease


我会快速的带你复习一下autorelease pools,然后深入的解释一下相关概念,这样你就能够理解autorelease pool和release之间的不同。


autorelease pool是存放autoreleased对象的地方。当这个autorelease pool被release时,所有的autoreleased对象会发送一个release消息。如果一个对象的引用计数为0,那个这个对象就会被deallocted。


在事件声明周期结束的时候,autorelease pool会被release。例如,当用户触摸了UI,一个新的事件声明周期会被创建来处理这次触摸事件,然后它处理相关触摸事件的所有理解,最后显示给用户。这就是一个事件声明周期。对于这个事件声明周期,你会有一个autorelease poo。


在main 方法中创建一个main autorelease pool,可以使用下面的代码:


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

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

       }

        return retVal;

  2. }


在代码中可以看到,在方法的开始部分,创建了一个新的autorelease pool,使用了UIApplicationMain处理了主要的逻辑;在事件循环之后,pool被release。整个周期如图7-1.


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

向AI问一下细节

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

AI