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

自动引用计数

目前创新互联建站已为成百上千家的企业提供了网站建设、域名、虚拟空间、网站托管运营、企业网站设计、启东网站维护等服务,公司将坚持客户导向、应用为本的策略,正道将秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。

上面的那样处理过程,使得问题变得更加复杂,因为你总是要记住内存管理的规则,你需要知道什么时候在代码中加入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。


本文名称:iOS优化内存,提升性能之二
文章源于:http://pwwzsj.com/article/jshhep.html