Objective-C中提供了兩種內(nèi)存管理機(jī)制MRC(Mannul Reference Counting)和ARC(Automatic Reference Counting),分別提供對(duì)內(nèi)存的手動(dòng)和自動(dòng)管理,來滿足不同的需求。注意的是Xcode 4.1及其以前版本沒有ARC,MRC與ARC的區(qū)別如圖1所示。需要理解MRC,但實(shí)際使用時(shí)強(qiáng)推ARC。

1. Objective-C語言中的MRC(MannulReference Counting)
在MRC的內(nèi)存管理模式下,與對(duì)變量的管理相關(guān)的方法有:retain,release和autorelease。retain和release方法操作的是引用記數(shù),當(dāng)引用記數(shù)為零時(shí),便自動(dòng)釋放內(nèi)存。并且可以用NSAutoreleasePool對(duì)象,對(duì)加入自動(dòng)釋放池(autorelease調(diào)用)的變量進(jìn)行管理,當(dāng)drain時(shí)回收內(nèi)存。
(1)retain,該方法的作用是將內(nèi)存數(shù)據(jù)的所有權(quán)附給另一指針變量,引用數(shù)加1,即retainCount+= 1;
(2)release,該方法是釋放指針變量對(duì)內(nèi)存數(shù)據(jù)的所有權(quán),引用數(shù)減1,即retainCount-= 1;
(3)autorelease,該方法是將該對(duì)象內(nèi)存的管理放到autoreleasepool中。
示例代碼:
//假設(shè)Number為預(yù)定義的類
Number* num = [[Number alloc] init];
Number* num2 = [num retain];//此時(shí)引用記數(shù)+1,現(xiàn)為2
[num2 release]; //num2 釋放對(duì)內(nèi)存數(shù)據(jù)的所有權(quán) 引用記數(shù)-1,現(xiàn)為1;
[num release];//num釋放對(duì)內(nèi)存數(shù)據(jù)的所有權(quán) 引用記數(shù)-1,現(xiàn)為0;
[num add:1 and 2];//bug,此時(shí)內(nèi)存已釋放。
//autoreleasepool 的使用 在MRC管理模式下,我們摒棄以前的用法,NSAutoreleasePool對(duì)象的使用,新手段為@autoreleasepool
@autoreleasepool {
Number* num = [[Number alloc] init];
[num autorelease];//由autoreleasepool來管理其內(nèi)存的釋放
}
對(duì)與Objective-c中屬性的標(biāo)識(shí)符可以總結(jié)為:
@property (nonatomic/atomic,retain/assign/copy, readonly/readwrite) Number* num;
(1)nonatomic/atomic,表示該屬性是否是對(duì)多線程安全的,是不是使用線程鎖,默認(rèn)為atomic,
(2)retain/assign/copy,是有關(guān)對(duì)該屬性的內(nèi)存管理的,
a、assign ** is the default. In the setter that is created by @synthesize, the value willsimply be assigned to the attribute, don’t operate the retain count. Myunderstanding is that "assign" should be used for non-pointer attributes.
b、retain** is needed when the attribute is a pointer to an object. The setter generated by@synthesize will retain (aka add a retain count) the object. You will need torelease the object when you are finished with it.
c、copy is needed when the object is mutable. Use this if you need the value of theobject as it is at this moment, and you don't want that value to reflect anychanges made by other owners of the object. You will need to release the objectwhen you are finished with it because you are retaining the copy.
(3)readwrite /readonly -"readwrite" is the default. When you @synthesize, both a getter and asetter will be created for you. If you use "readonly", no setter willbe created. Use it for a value you don't want to ever change after the instantiationof the object.
2. Objective-c語言中的ARC(AutomaticReference Counting)
在ARC中與內(nèi)存管理有關(guān)的標(biāo)識(shí)符,可以分為變量標(biāo)識(shí)符和屬性標(biāo)識(shí)符,對(duì)于變量默認(rèn)為__strong,而對(duì)于屬性默認(rèn)為unsafe_unretained。也存在autoreleasepool。
對(duì)于變量的標(biāo)識(shí)符有:
(1) __strong,is the default. An object remains “alive” as long as there is a strong pointerto it.
(2) __weak,specifies a reference that does not keep the referenced object alive. A weakreference is set to nil when there are no strong references to the object.
(3)__unsafe_unretained,specifies a reference that does not keep the referenced object alive and is notset to nil when there are no strong references to the object. If the object itreferences is deallocated, the pointer is left dangling.
(4)__autoreleasing,is used to denote arguments that are passed by reference (id *) and areautoreleased on return,managedby Autoreleasepool.
對(duì)于變量標(biāo)識(shí)符的用法:
__strong Number* num = [[Number alloc]init];
在ARC內(nèi)存管理模式下,其屬性的標(biāo)識(shí)符存在以下幾種:
@property(nonatomic/atomic, assign/retain/strong/weak/unsafe_unretained/copy,readonly/readwrite) Number* num;//默認(rèn)為unsafe_unretained
其中assign/retain/copy與MRC下property的標(biāo)識(shí)符意義相同,strong類似與retain,assign類似于unsafe_unretained,strong/weak/unsafe_unretained與ARC下變量標(biāo)識(shí)符意義相同,只是一個(gè)用于屬性的標(biāo)識(shí),一個(gè)用于變量的標(biāo)識(shí)(帶兩個(gè)下劃短線__)。所列出的其他的標(biāo)識(shí)符與MRC下意義相同。
(1)對(duì)于assign,你可以對(duì)標(biāo)量類型(如int)使用這個(gè)屬性。你可以想象一個(gè)float,它不是一個(gè)對(duì)象,所以它不能retain、copy。
(2)對(duì)于copy,指定應(yīng)該使用對(duì)象的副本(深度復(fù)制),前一個(gè)值發(fā)送一條release消息?;旧舷駌etain,但是沒有增加引用計(jì)數(shù),是分配一塊新的內(nèi)存來放置它。特別適用于NSString,如果你不想改變現(xiàn)有的,就用這個(gè),因?yàn)镹SMutableString,也是NSString。
對(duì)于Core Foundation與objective-cObject進(jìn)行交換時(shí),需要用到的ARC管理機(jī)制有:
(1) (__bridge_transfer<NSType>) 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<CFType>) 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.