iOS arc VS mrc学习笔记

一、* Core Foundation与objective-c Object进行交换 *

对于Core Foundation与objective-cObject进行交换时,需要用到的ARC管理机制有:

(1) (__bridge_transfer) op or alternatively CFBridgingRelease(op) is used to consume a retain-count of a CFTypeRef while transferring it over to ARC. This could also be represented by

        id someObj =(__bridge <NSType>) op; 
       CFRelease(op);

(2) (__bridge_retained) op or alternatively CFBridgingRetain(op) is used to hand an NSObject over to CF-land while giving it a +1 retain count. You should handle a CFTypeRef you create this way the same as you would handle a result of CFStringCreateCopy().This could also be represented by

CFRetain((__bridge CFType)op); 
CFTypeRef someTypeRef =(__bridge CFType)op;

(3) __bridge just casts between pointer-land and Objective-C object-land. If you have no inclination to use the conversions above, use this one.

二、* ARC和IOS4 *

ARC在IOS4是没有 __weak 关键字的,需要使用 unsafe_unretained来代替。

三、* ARC中的内存泄露 *

使用了ARC也并不意味着我们的工程里面不会出现内存泄露了。在ARC机制下,最常见导致内存泄露的是循环强引用。容易出现的场合有:

①Outlet类型指针

Outlet类型的指针变量应该用weak属性来声明

②委托

一定要将delegate的属性设为weak,原因我就不解释了,实在不明白,请猛击这里

③block

下面这段代码,在MRC条件下是没有问题的:

MyViewController * __block myController = [[MyViewController alloc] init…];  
// ...  
myController.completionHandler =  ^(NSInteger result) {  
    [myController dismissViewControllerAnimated:YES completion:nil];  
}; 

但是在ARC条件下,就会内存泄露,导致myController指向的对象无法释放。
原因是,__block id x声明的变量x用于block中时,MRC条件下是不会增加x的引用计数,但是在ARC条件下,会使x得引用计数加一,请各位务必注意!!!!!!!!!!!!

上述问题代码有以下几种解决方案:

方案一:

MyViewController * __block myController = [[MyViewController alloc] init…];  
// ...  
myController.completionHandler =  ^(NSInteger result) {  
    [myController dismissViewControllerAnimated:YES completion:nil];  
    myController = nil;  
}; 

最简单的解决办法,在block中使用完myController时,是它指向nil,没有strong类型的指针指向myController指向的对象时,该对象就回被释放掉。

方案二:

MyViewController *myController = [[MyViewController alloc] init…];  
// ...  
MyViewController * __weak weakMyViewController = myController;  
myController.completionHandler =  ^(NSInteger result) {  
    [weakMyViewController dismissViewControllerAnimated:YES completion:nil];  
};  

该方案使用了一个临时的__weak类型的指针weakMyViewController,在block中使用该指针不会导致引用计数加一,但却存在隐患,当该对象在外部被释放时,block里面执行的操作就无效了。下面的方案三可以解决这个问题。

方案三:

MyViewController *myController = [[MyViewController alloc] init…];  
// ...  
MyViewController * __weak weakMyController = myController;  
myController.completionHandler =  ^(NSInteger result) {  
    MyViewController *strongMyController = weakMyController;  
    if (strongMyController) {  
        // ...  
        [strongMyController dismissViewControllerAnimated:YES completion:nil];  
        // ...  
    }  
    else {  
        // Probably nothing...  
    }  
};  

即在block中使用myController对象之前再声明一个临时的strong类型的指针,指向weak类型的指针,这时strongMyController指针就变成了有效的强引用,其指向的对象就能保证不被释放掉。

④定时器

定时器也是非常容易产生内存泄露的地方。比如下面的代码

@implementation AnimatedView  
{  
  ?NSTimer *timer;  
?}  

- (id)initWithCoder:(NSCoder *)aDecoder  
{  
?  
?  if ((self = [super initWithCoder:aDecoder])){  
    timer = [NSTimer scheduledTimerWithT    imeInterval:0.1  
    target:self  
    selector:@selector(handleTimer:)  
    userInfo:nil  
    repeats:YES];  
  }  
  return self;  
}  
- (void)dealloc  
{   
  [timer invalidate];  
}  
- (void)handleTimer:(NSTimer*)timer  
{  
  //do something  
}  

乍一看这段代码没啥问题,但是运行起来才发现dealloc方法是不会被调用的,self有一个timer的强引用,timer又有一个self的强引用,典型的循环引用!

解决方法是将timer的属性设置为__weak。

四、* @autoreleasepool 和 NSAutoreleasePool *

ARC中是不支持使用NSAutoreleasePool的,但是可以使用@autoreleasepool代替。@autoreleasepool既可以用在ARC环境中,也可以用在非ARC环境中,而且效率要比前者高,苹果官网中是这样描述的:

ARC provides @autoreleasepool blocks instead. These have an advantage of being more efficient than NSAutoreleasePool. 

五、* 使用ARC需要遵守的新规则 *

①不要在dealloc方法中调用[super dealloc];

②不能使用 retain/release/retainCount/autorelease

③不能使用 NSAllocateObject/NSDeallocateObject

④不能使用 NSZone

⑤Objective-C 对象不能作为C语言结构体(struct/union)的成员

参考链接:

  1. arc & mrc这不是技术路线问题。

  2. Objective-c的内存管理MRC与ARC

  3. ARC使用心得(二)

  4. Performance Comparison: cocos2d-iphone v2 vs v3 vs Sparrow and ARC vs MRC

  5. iPhone开发之深入浅出 (4) — ARC之循环参照
  6. Transitioning to ARC Release Notes

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。