**:
這是 看 書籍 objective-c 高階程式設計 ios與os x多執行緒和記憶體管理 一書的隨記。
除錯
1.檢視 autoreleasepool 池裡面的物件
extern
void
_objc_autoreleasepoolprint();
_objc_autoreleasepoolprint
();
---------------上面的這個私有函式本人在ios呼叫一直沒有輸出,mac怎有。。。----------是**錯了嗎??
2.通過 clang 可以 檢視對應的 彙編**。其實xcode 的 product-》perform action ->assemble "" 也就ok了
clang -fobjc-arc -framework foundation test.m -o test
3 通過 cfgetretaincount((__bridge cftyperef)test2)); 或者
extern
uintptr_t
_objc_rootretaincount();
nslog
(@"***x %lu"
,_objc_rootretaincount
(self
.array
));
可以在 arc 總看到 retaincount 的值。切記 不要依賴這個retaincount 編譯器 有很多優化。可能跟你理解的不同。比如 當你 通過乙個非 alloc new copy mutablecopy 方法獲取乙個物件的時候 按照道理是 獲取的 autorelease 物件。然後在 retain 。編譯器 會優化省略 autorelease 過程。
自己生成的物件,自己所持有
非自己生成的物件,自己也能持有
不在需要自己持有物件時釋放
非自己持有的物件 無法釋放
方法名稱 以 alloc new copy mutablecopy 開頭的方法 必須返回給呼叫者應當持有的物件。
以init 開頭的 更加嚴格 必須返回 id 型別 或者當前類的 型別 或者 子類父類。這個物件不會註冊到 autorelease 池裡面去。只是
_strong
id 型別 和物件型別 預設的修飾符。即:
id xx = [[nsobject alloc] init]; 實際上就等於
id _strong obj = [[nsobject alloc] init ];
簡單的說 就是當 strong 修飾符修飾的變數 被賦值的時候。 就相等於 retain 了該物件。 當該修飾符 修飾的變數 拋棄原本指向的物件的時候。 就相當於 release了 該物件。當strong 修飾的變數結束了有效區域的時候。也會release
[objc]view plain
copy
mytest *test = [[mytest
alloc
]init];
mytest *test2
= test;
mytest *test3
= test;
mytest *test4
= test;
mytest *test5
= test;
nslog(@"retain count is %ld"
, cfgetretaincount((__bridge
cftyperef)test));
test5
=nil
; nslog(@"retain count is %ld"
, cfgetretaincount((__bridge
cftyperef)test));
test4
= [[mytest
alloc
]init];
nslog(@"retain count is %ld"
, cfgetretaincount((__bridge
cftyperef)test));
如上**所示。因為預設修飾符是strong 所以 當test 賦值給strong修飾的變數的時候。 就retain了 test。所以第乙個輸出是5. 當 執行 test5 = nil 的時候。 因為 被修飾符為 strong 的變數 拋棄的物件會release 所以 變成了4. 同樣道理 最後 test retaincount 變成了3;(ps:這裡要說的是 之前在有的資料看過 非arc 跟 arc 混編的 複雜情況下 有可能導致的記憶體洩露。 主要是 物件是非arc 建立的 在 arc中使用的情況。 當時 給出的解決方案。就是 用完之後 設定為 nil 就行了。 想想這裡的了解。其實有一定道理。當然現在找不到那個資料了所以 也沒法實驗總結)
_weak
當2個物件互相引用導致引用環的時候就需要weak了。 簡單的說就是賦值的時候 不改變 retaincount的概念。當然還有當物件釋放之後 會設定為 nil。這也是 _weak 和 __unsafe_unretain 的主要區別。
這裡有個需要注意的。當使用__weak 變數的時候。不是簡單的訪問。 是會呼叫乙個方法 retainweakreference (可以重寫這個非公開方法 用來除錯。但正式開發千萬別加邏輯。) 書上說 會加入到 autoreleasepool 裡面去。可是訪問結束檢視 autoreleasepool 。在使用訪問 __weak的時候 也確實可以檢視到 retaincount 增加了1. 這裡可以 猜測 是只是訪問的那裡新建了乙個 autoreleasepool池。訪問結束 就 已經釋放了。
這樣的作用是因為 weak 不持有該物件。當訪問過程中。可能被釋放掉。 這樣就能保證訪問過程中都是有效狀態。
_unsafe_unretained
我能想到的跟 __weak 的區別就是 釋放了物件的時候 不設定為 nil。用這個修飾符的物件 不被arc記憶體管理 所管理。
_autoreleaseing
autorelease 的本質就是 建立乙個nsautoreleasepool 物件。當乙個物件呼叫 autorelease 的時候。 會去獲取當前使用的 最內側(如果有巢狀的池的話)的nsautoreleasepool物件。然後呼叫 nsautoreleasepool物件的乙個 類似陣列 的addobject 方法。讓 nsautoreleasepool物件來持有這個 autorelease 物件。 當呼叫 nsautoreleasepool 的 drain方法的時候。清除引用。 就釋放了 autorelease物件。
實際上在arc 中 。編譯器有很多優化。讓原本是autorelease 的物件 根本就不加入到 nsautoreleasepool中去。
pd:這裡需要注意的是 指標變數 預設的修飾符 是 autoreleaseing 比如 id *xx。 是 autoreleaseing的 而 id xx 是 strong的。
屬性修飾符
assign
__unsafe_unretained
copy
__strong(是retain的複製的新物件)
retain
__strong
strong
__strong
unsafe_unretained
__unsafe_unretained
weak
__weak
這裡 感覺沒有太多的東西需要了解。 只要了解了修飾符 就會知道屬性的這些含義了。 需要注意的是 有人喜歡在類裡面的方法裡面對屬性複製的時候 用 下劃線開頭的變數。這裡不建議這樣做。 除了 初始化方法 delloc方法,以及 set get 方法內部。 其他地方 對屬性賦值的時候 盡量用屬性訪問。這是為了維護好屬性的 copy strong 等。
另外這裡測試的時候 發現 如果在方法裡面 有個 __weak屬性 每次使用 屬性都會導致retaincount +1. 檢視彙編** 有個
_objc_retainautoreleasedreturnvalue 方法被呼叫了。完全不知道為什麼。。
看了下 _objc_autoreleasedreturnvalue 函式 返回 註冊到 autoreleasepool 裡面的物件。 但是 跟 autorelease 函式又不同。 如果 _objc_autoreleasedreturnvalue 方法之後 會立即呼叫 _objc_retainautoreleasedreturnvalue 就不將物件註冊到 autoreleasepool 中。而是直接傳遞到方法或者函式的呼叫方。 _objc_retainautoreleasedreturnvalue 和 objc_retain 函式不同。 這個作用 就是 上面說到的。 對於不是 new alloc copy mutablecopy 開頭的方法。按道理返回的物件是 autorelease 然後在retain 。這個機制就優化了這裡的**
IOS開發記憶體釋放小結
記憶體釋放是iphone開發過程中比較重的地方,所以在開闢記憶體後,我們必須小心 謹慎 並且及時的釋放掉。記憶體的釋放,可以呼叫dealloc函式,該函式可以釋放,該類物件所占用的記憶體空間,為iphone節省寶貴的記憶體資源。那麼dealloc函式是什麼時候釋放的哪?測試 如下 我們先建立乙個類 ...
iOS效能小結
最簡單的工具就是 nsdate,但精度不是太好。nsdate tmpstartdata nsdate date retain you code here.double deltatime nsdate date timeintervalsincedate tmpstartdata nslog cos...
記憶體對齊小結
原則1 結構體的資料成員,第乙個資料成員放到 0 的位置,以後每個資料成員的起始位置要從該成員大小或成員子成員大小 如陣列 的整數倍開始 原則2 結構體作為成員,如果乙個結構中有某些結構體成員,則結構體成員要從其內部最大的整數倍位址開始儲存 struct a中公有struct b,b中有char,i...