温馨提示×

温馨提示×

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

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

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

发布时间:2020-08-01 04:36:43 来源:网络 阅读:500 作者:iKingLai 栏目:移动开发

自动引用计数


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




向AI问一下细节

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

AI