Objective-c中提供了兩種內存管理機制MRC(MannulReference Counting)和ARC(Automatic Reference Counting),分別提供對內存的手動和自動管理,來滿足不同的需求。注意的是Xcode 4.1及其以前版本沒有ARC,MRC與ARC的區別如圖1所示。需要理解MRC,但實際使用時強推ARC。
圖1 MRC與ARC區別示意圖
1. Objective-c語言中的MRC(MannulReference Counting)
在MRC的內存管理模式下,與對變量的管理相關的方法有:retain,release和autorelease。retain和release方法操作的是引用記數,當引用記數為零時,便自動釋放內存。並且可以用NSAutoreleasePool對象,對加入自動釋放池(autorelease調用)的變量進行管理,當drain時回收內存。
(1) retain,該方法的作用是將內存數據的所有權附給另一指針變量,引用數加1,即retainCount+= 1;
(2) release,該方法是釋放指針變量對內存數據的所有權,引用數減1,即retainCount-= 1;
(3) autorelease,該方法是將該對象內存的管理放到autoreleasepool中。
示例代碼:
//假設Number為預定義的類
Number* num = [[Number alloc] init];
Number* num2 = [num retain];//此時引用記數+1,現為2
[num2 release]; //num2 釋放對內存數據的所有權 引用記數-1,現為1;
[num release];//num釋放對內存數據的所有權 引用記數-1,現為0;
[num add:1 and 2];//bug,此時內存已釋放。
//autoreleasepool 的使用 在MRC管理模式下,我們摒棄以前的用法,NSAutoreleasePool對象的使用,新手段為@autoreleasepool
@autoreleasepool {
Number* num = [[Number alloc] init];
[numautorelease];//由autoreleasepool來管理其內存的釋放
}
對與Objective-c中屬性的標識符可以總結為:
@property (nonatomic/atomic,retain/assign/copy, readonly/readwrite) Number* num;
(1) nonatomic/atomic,表示該屬性是否是對多線程安全的,是不是使用線程鎖,默認為atomic,
(2) retain/assign/copy,是有關對該屬性的內存管理的,
l 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.
l "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.
l "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.