《Objective-C 高級編程》學習筆記2-Blocks
編程
GNUstep 是 Cocoa 框架的互換框架函數
2.2.一、GNUstep 中 alloc 類方法實現的簡化版:post
struct obj_layout {
NSUInteger retained;
};
+ (id)alloc {
int size = sizeof(struct obj_layout) + 對象大小;
struct obj_layout *p = (struct obj_layout *)calloc(1, size);
return (id)(p + 1);
}複製代碼
2.2.二、alloc 返回對象的內存圖:學習
2.2.三、GNUstep 內存管理總結:ui
// __CFDoExternRefOperation 函數按 retainCount/retain/release 操做進行分發調用不一樣函數
// NSObject 類的相關方法實現以下:
- (NSUInteger)retainCount {
return (NSUInteger)__CFDoExternRefOperation(OPERATION_retainCount, self);
}
- (id)retain {
return (id)__CFDoExternRefOperation(OPERATION_retain, self);
}
- (void)release {
__CFDoExternRefOperation(OPERATION_release, self);
}複製代碼
GNUstep 將引用計數保存在對象佔用內存塊頭部的變量中,spa
蘋果則是保存在引用計數表的記錄中:
3d
經過內存塊頭部管理引用計數的好處:指針
經過引用計數表管理引用計數的好處:code
OC 編程中爲了處理對象,可將變量類型定義爲 id 類型或各類對象類型:
ARC有效時,id類型和對象類型必須附加全部權修飾符:
3.1.一、__strong修飾符:默認的全部權修飾符
__strong修飾符表示對對象的「強引用」。持有強引用的變量在超出其做用域時被廢棄,隨着強引用的失效,引用的對象會隨之釋放。
3.1.二、__weak修飾符:避免引用循環,弱引用不能持有對象實例
循環引用容易形成內存泄漏,內存泄漏就是應當廢棄的對象在超出其生存週期後繼續存在。
__weak修飾符,在持有某對象的弱引用時,若該對象被廢棄,則此弱引用將自動失效且處於nil被賦值的狀態。
3.1.三、__unsafe_unretained修飾符:在iOS如下中用來代替__weak
附有__unsafe_unretained修飾符的變量不屬於編譯器的內存管理對象
賦值給附有__unsafe_unretained修飾符變量的對象在經過該變量使用時,若是沒有確保其確實存在,則應用程序會崩潰。
3.1.四、__autoreleasing修飾符
ARC有效時,指定「@autoreleasepool塊」替代「NSAutoreleasePool」類,用附有 __autoreleasing 修飾符的變量替代 autorelease 方法。
不使用 __autoreleasing 修飾符也能使對象註冊到 autoreleasepool。因爲return使強引用持有的對象超出做用域會被釋放,但該對象做爲函數的返回值,編譯器會自動將其註冊到 autoreleasepool。
在訪問附有 __weak 修飾符的變量時,實際上一定要訪問註冊到 autoreleasepool 的對象。
在 ARC 有效的狀況下編譯源代碼,必須遵照必定的規則:
3.2.三、ARC 有效時須遵照內存管理的方法命名規則
在 ARC 無效時,用於對象 生成/持有 的方法必須遵照命名規則:
在 ARC 有效時,以上規則沒有改變。只是要追加一條命名規則:
當 ARC 有效時,Objective-C 類的屬性也會發生變化: