2013年3月23日星期六

ARC实践

http://iosdevelopersnote.blogspot.com/2012/08/arc-automatic-referece-couting.html

討論的對像是針對 @property 這個應用,不同的對象應該用那一種修飾
  • 數值型別 -assign
@property (assign) int numbers; @property (assign) CGPoint center;
  • id 或者說物件型別需要被 retain 的物件或者說在 object graph (註1) 中向下參考的物件 - strong
in Car.h@property (strong) Engine * kernel;
  •  應用 Protocol 的物件或是在 object graph 中向上參考的物件 - weak
in Engine.h@property (weak) Car * owner;  // 向上參考的物件
          @property (weak) id<SomeDelegate> delegate ; // delegate 的應用
  • Block 物件 -  copy
 typedef  void (^BlockType) (int a) ;
@property (copy) BlockType someBlock;
  •  IBOutlet 大部分是 weak 只有最上層的 IBOutlet ( View Controller 的 view )是 strong
Bridging - C 型別 (Core Fundation ) 以下簡稱 CF 和 Objective-C ( Foundation ) 以下簡稱 F 型別轉換時,有關記憶體管理應該注意的地方

  • __bridge - 沒有改變 retain count (注意是有兩個下底線),可以適用在 CF 轉 F 或是 F 轉 CF
  • __bridge_transfer - 用在 CF 轉 F 的時候,會將 CF 的 retain count 減 1
  • __bridge_retained - 用在 F 轉 CF 的時候,會將 F 的 retain count 加 1
我們來看幾個例子
ARC 寫法 - __bridge_transfer 
id obj = (__bridge_transfer ) cf; // 預設是 __strong id obj ;
換成 non-ARC 的寫法的時候是 
id obj = (id) cf;
[obj retain];  // strong 的關系
[(id) cf release]; //transfer 的關系

ARC 寫法 - __bridge_retained
id obj = [[NSObject alloc] init];
void *cf = (__bridge_retained void *) obj;
換成 non-ARC 的寫法的時候是 
id obj = [[NSObject alloc] init];
void * cf = obj;
[(id) cf retain];
此寫法通常最後會加上一個  CFRelease(cf) 來保持 retain count 平衡 
另外有兩個方便的 function 可以用

CFTypeRef CFBridgingRetain(id X) {
     return (__bridge_retained CFTypeRef)X;
}

id CFBridgingRelease(CFTypeRef X) { 
    return (__bridge_transfer id)X;
}
id obj = (__bridge_transfer ) cf;
可以改寫成
id obj =CFBridgingRelease(cf);

void *cf = (__bridge_retained void *) obj;
可以改寫成
void *cf = CFBridgingRetain (obj);

没有评论:

发表评论