8赞
668
当前位置:  开发笔记 > 编程语言 > 正文

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

自动引用计数上面的那样处理过程,使得问题变得更加复杂,因为你总是要记住内存管理的规则,你需要知道什么时候在代码中加入retain,release,或者auto

自动引用计数


上面的那样处理过程,使得问题变得更加复杂,因为你总是要记住内存管理的规则,你需要知道什么时候在代码中加入retain,release,或者autorelease。因此,在新版Xcode(Xcode4.2),苹果发布了一个新的机制,使得retain,release,和autorelease自动执行。上面所有的策略依然可以应用在新版本的代码中。但是Xcode会为你添加内存管理需要的代码。


为了给你一个快速的了解,我重新编写Listing 7.1和Listing 7.2代码。


Listing 7.4. Rewrite Code for the New ARC mechanism

For Listing 7.1:
- (void)doSomething {

   NSObject *obj = [[NSObject alloc] init];

   NSLog(@"obj: %@", obj);

}

For Listing 7.3:
- (NSObject *)getObj {

       NSObject *obj = [[NSObject alloc] init];

       return obj;

}


就是这样!不在需要release或autorelease。当你编译代码的时候,Xcode会自动的为你添加release/autorelease相关代码。在编译器添加这些调用后,代码就和Listing 7.1和Listing 7.3一样了。


如何在Xcode中设置你的工程?


进入你的工程的settings,查找Objective-C Automatic ReferenceCounting是否设置为YES。你可以在图7-2的看到设置行的位置:


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


如果有一个已经使用了retain/release/autorelease的工程,你可以使用Xcode的migration工具来删除这些不需要的代码,如图7-3 。


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


ARC策略


你需要遵守一些新的规则来确保你的工程兼容ARC:

  • 你不能使用或调用旧的内存管理方法:retain,release,autorelease和retainCount。你可以复写dealloc方法做任何你需要清理的工作,但是你不能调用dealloc方法,例如[super dealloc]是不允许的。

       

       在构建属性的时候,这个规则也是强制要求的:


  1. @property (nonatomic, retain) NSString *myName; // 这是不允许的


  • 在c中不能使用对象指针,这会导致很多问题,如果你想在你的工程中集成c代码,如第9章所描述。你不能使用NSAutoreleasePool对象,必须使用@autoreleasepool。



       不能使用:

       

  1. NSAutoreleasePool *myPool = [[NSAutoreleasePool alloc] init];

  2. // your code here
    [pool release];

   

       必须使用:


  1. @autoreleasepool {

  2. // your code here

    }




ARC新的修饰符


根据新的ARC策略,你现在需要包含新的生命周期的修饰符来运用新的ARC规则。

  • strong:这个表示你想保持一个变量的强引用。只要有对象A的一个强引用,对象A就不会deallocated。

  • weak:这个和assign类似,如果你只是想要保持一个对象的引用,而又不想显示的拥有它。因此,你不需要管理这个对象的生命周期。一个比较好的情况是:如果对象A有对象B的一个弱引用,如果对象B被deallocated,那么这个引用会变成nil。这样是比较安全的,因为你不会拥有一个已经deallocated对象的引用。

  • unsafe_unretained:这个和weak类似,他们的不同之处是:对象A有对象B的一个引用,如果对象B被deallocated了,那么对象A的引用就会指向一个deallocated对象,这样会导致应用程序崩溃。

  • autoreleaseing:如果你有一个方法需要引用传递的参数,你可以考虑这个修饰符。当返回的时候,方法会负责autorelease这个参数。



对象属性


现在,你需要改变对象属性的声明。不要在使用之前版本的旧的内存管理机制:@property (retain) NSString *myString,现在有一个新的规则。


如果你想拥有一个对象的所有权


// This is similar to @property (retain) NSString *myString

@property(strong) NSString *myString;


如果你只是要持有一个对象的引用,而不是它的所有权


// This is similar to @property (assign) UIViewController *myViewController;

// except that if myViewController object is deallocated,
// the reference becomes nil.
@property(weak) UIViewController*myString;



注意:如果你想要你的应用运行在iOS4,你不能使用weak。你需要使用unsafe_unretained然后自己设置引用为nil。




变量声明


为了在方法内部使用这些修饰符,你需要在它的前面添加__(两个下划线)。例如,你可以使用__strong或__weak。在方法中,__strong是默认的修饰符。


使用__strong修饰符能确保你的对象一直存在直到方法结束,同时要小心使用__weak或__unsafe_unretained。如果没有强引用指向你的对象,你的对象会立即崩溃。例如:


NSString __weak *myString = @"hello world";

NSLog (@"myString: %@", myString);



将会打印(null),因为在打印时,已经没有强引用指向它。


__autoreleasing修饰符用来给方法接收一个引用传递的参数。


- (BOOL)performTaskWithError:(NSError *__autoreleasing *)error;


你可以正常的调用它:


NSError *error = nil;
[self performTaskWithError:&error];


默认,error对象声明为强引用,但是编译器会添加代码使得调用方法[self performTaskWithError:&error] ;



注意:对于返回对象的所有方法,同时没有包含new,alloc或copy,对象在返回是会自动的变为autoreleased。





推荐阅读
  • structBITMAPFILEHEADER{publicshortbfType;publicintbfSize;publicshortbfReserved1;publicshor ... [详细]
  • as运算符用于执行引用类型的显式类型转换。如果要转换的类型与指定的类型兼容,转换就会成功进行;如果类型不兼容,as运算符就会返回null值。如下面的代码所示,如果object引用实 ... [详细]
  • centos7.4二进制安装mysql
    centos7.4二进制安装mysql ... [详细]
  • jqBash,unfortunately,doesn’tshipwithacommandthatcanworkwithJSONnatively.Inthislesson,we’ll ... [详细]
  • CentOS7安装docker启动报错
    执行yuminstalldocker-y命令安装docker然后启动服务systemctlstartdocker,服务启动失败查询日志文件varlogmessages,显示报错:E ... [详细]
  • eg:把当前系统使用率最高的前10个命令的命令名输出,并统计命令使用的次数。awk‘{comm[$1]++}END{for(iincomm){printi,comm[i]}}‘ro ... [详细]
  • HelloWord程序C语言代码#includevoidmain(){printf(HelloWord\n);}要了解一个helleword程序的运行,首先要 ... [详细]
  • 顺序表(线性表的顺序存储结构)及C语言实现
    逻辑结构上呈线性分布的数据元素在实际的物理存储结构中也同样相互之间紧挨着,这种存储结构称为线性表的顺序存储结构。也就是说,逻辑上具有线性关系的数据按照前后的次序全部存储在一整块连续 ... [详细]
  • 一、知识普及1、蓝牙4.0分为两个部分:1)BluetoothReady,兼容传统蓝牙的高速部分;2)BluetoothSmart,BLE(BluetoothLowEnergy), ... [详细]
  • 如何彻底的做到代码和界面分离(转载.......)http://www.cnblogs.com/netfocus/articles/1035635.html ... [详细]
  • C01++val;优于val++;对数量不定的输入数据:while(cinvalue)遇到无效的输入或eof后,cin变为无效状态,条件变为假。来自标准库的头文件用包围, ... [详细]
  • ( 17 )MySQL中的触发器
    MySQL中的触发器触发器需求:有两张表,一张定单表,一张商品表.每生成一个订单,商品库存就相应减少.触发器(trigger)事先为某张表绑定好一段代码,当某些内容发生改变的时候( ... [详细]
  • 软件测试培训WebDriver为了支持PageObject模式,内置了一个PageFactory的工厂类。接下来本文通过一个案例来讲下如何使用PageFactory。首先定义一个P ... [详细]
  • 如何解决《单元测试自定义WebAPIAuthorizeAttribute》经验,需要怎么解决? ... [详细]
  • 视频播放相关内容总结
    视频播放相关内容总结多媒体常识:什么是多媒体多媒体是计算机和视频技术的结合,实际上它是两个媒体;声音和图像,或者用现在的术语:音响和电视常用的视频格式Andr ... [详细]
author-avatar
聂依依mma
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有