ARC與MRC

1、經過引用計數管理內存 ios

一、引用計數。經過引用計數管理內存。對象被建立出來時,引用計數至少爲1,經過retain使引用計數遞增,經過release、autorelease使引用計數遞減,引用計數爲0時,對象所在的內存爲可重用,全部指向該對象的引用都無效。數據結構

二、dangling pointer。指向對象的引用計數爲0的引用。使用dangling pointer不必定使程序崩潰,崩潰是否,看對象內存是否被覆寫。異步

三、引用樹。ios應用程序中的root object爲UIApplication對象。socket

四、屬性存取。strong relationship修飾的屬性,在setValue時,先保留新值,再釋放舊值。這個順序不能顛倒,一旦顛倒,假如新值和舊值爲同一個對象,釋放後有可能對象已被回收,再保留就會出現問題。函數

五、autorease。在return方法內部建立的對象時,因爲不能在方法內部釋放對象(對象引用計數值有可能爲0,對象就被回收),就得經過autoreleasepool使引用計數值在下一次event loop時遞減。經過類工廠方法建立的對象放置在autoreleasepool中。oop

六、retain cycle。致使內存泄漏,解決問題有兩種辦法,一是weak reference,一是代碼控制其中的某個對象再也不保留另一個對象。性能

七、Clang編譯器中的靜態分析器(static analyzer)。能夠查明內存管理問題,也能夠根據須要,預先加入保留與釋放操做。spa

注意:retaincount方法獲取引用計數值是不太有用的。對引用計數器作遞增或遞減操做時,只能說作了遞增或遞減操做,而毫不能說保留計數必定是某個值。code

 

2、ARC自動引用計數(編譯器與運行期組件共同管理內存)對象

一、實現思路是static analyzer。

二、代碼中存在retain、release、autorelease、dealloc時,編譯器沒法經過。在調用這些方法時,不經過oc的消息派發機制,直接調用底層的c語言函數。

三、ARC命名規則。以alloc、new、copy、mutableCopy開頭的方法名,對象歸方法調用者持有。詳解以下:

/* newPerson方法中,方法調用者持有返回對象。所以在方法內部,除了allo使引用計數+1外,沒有其他的保留與釋放操做,最後在調用方法後,對象須要增長一次釋放操做。*/
+ (Person *)newPerson{
    Person *person = [[person alloc] init];
    return person;
}
/*createPerson方法中,方法調用者不持有返回對象,所以在return操做時,ARC會增長 [person autorelease] 方法。最後計數器平衡。*/
+ (Person *)createPerson{
    Person *person = [[person alloc] init];
    return person;
}

 

四、ARC有時會成對移除保留、釋放操做。

五、ARC包含運行期組件。

若是方法名沒遵照命名規則,但返回值賦值給強引用修飾的變量,無疑須要增長retain操做。考慮到backward compatibility性能,createPerson方法的return語句不用[person autorelease]替換,而改用objc_autoreleaseReturnValue(person)替換。

objc_autoreleaseReturnValue方法底層實現。此方法會檢視方法返回後,是否要執行retain操做。若是要執行retain操做,則會設置全局數據結構中的一個標誌位,而且方法中的return對象不會自動釋放。並且在執行retain操做時,[person retain]也會用 objc_retainAutoreleaseReturnValue(person)方法代替,檢查到標誌位已經置位,則不執行保留操做。

設置標誌位和檢查標誌位是否已置位(編譯器執行),比保留和釋放快。

 

六、ARC中局部變量與實例變量修飾符。

strong:保留此值,默認語義;

weak:不保留此值,而且值被回收後,指向nil;

 

七、ARC中的dealloc方法。

1)、dealloc方法不容許發送release消息,不容許給父類發送dealloc消息。ARC藉助Objective-C++的一項特性生成清理例程(Objective-C++特性:回收Objective-C++對象時,待回收對象會調用全部C++對象的析構函數,編譯器發現對象中存在C++對象,就會生成.cxx_destruct方法)在.cxx_destruct方法中自動生成代碼,包括給父類發送dealloc消息。單例對象不會自動析構

2)、必要時添加CFRealease(Core Foundation對象)、free(經過malloc()分配的內存)方法、註銷通知等等。ARC中的dealloc方法僅釋放引用並解除監聽

3)、釋放引用不包括file descriptor、socket、大塊內存等,一般建立另外一個方法來釋放這些引用,且另外一個方法的調用必須在dealloc執行以前。不在dealloc中釋放這些資源的緣由:一是經過dealloc釋放,資源保留時間過長;二是dealloc方法不必定執行。

4)、執行異步任務的方法不該在dealloc中調用,只能在正常狀態下執行的方法也不該在dealloc中調用。

 

八、ARC中可能出現內存泄露的地方:

1)、出現相互強引用,致使雙方都沒法釋放(retain cycle);

2)、c代碼的對象,是不會本身釋放的,好比cg(CoreGraphics.frameworks)開頭的對象。

3)、GCD對象。

相關文章
相關標籤/搜索