一、 迴圈retain的場景
• 比如a物件retain了b物件,b物件retain了a物件
• 迴圈retain的弊端
• 這樣會導致a物件和b物件永遠無法釋放
• 迴圈retain的解決方案
當兩端互相引用時,應該一端用retain、一端用assign(weak)
二、@class
1、@class的使用
在.h檔案中使用@class引用乙個類
在.m檔案中使用#import包含這個類的.h檔案
@class 和 #import 的區別
這兩種的方式的區別在於:
1)#import方式會包含被引用類的所有資訊,包括被引用類的變數和方法;@class方式只是告訴 編譯器在a.h檔案中 b *b 只是類的宣告,具體這個類裡有什麼資訊,這裡不需要知道,等實現文 件中真正要用到時,才會真正去檢視b類中資訊;
2)使用@class方式由於只需要只要被引用類(b類)的名稱就可以了,而在實現類由於要用到被 引用類中的實體變數和方法,所以需要使用#import來包含被引用類的標頭檔案;
3)通過上面2點也很容易知道在編譯效率上,如果有上百個頭檔案都#import了同一 個檔案,或 者這些檔案依次被#improt(a->b, b->c,c->d…),一旦最開始的標頭檔案稍有改動,後面引用到這 個檔案的所有類都需要重新編譯一遍,這樣的效率也是可想而知的,而相對來 講,使用@class方 式就不會出現這種問題了;
所以:我們實際開發中盡量在.h標頭檔案中使用@class
4)對於迴圈依賴關係來說,比方a類引用b類,同時b類也引用a類,b類的**:
當程式執行時,#import編譯會報錯,
三、nsstring的記憶體管理問題
1—> nsstring *str = [[nsstring alloc] initwithstring:@」abc」];
2—> str = @」123」;
3—> [str release];
4—> nslog(@」%@」,str);
首先,咱們先對這段**進行分析。
第一句 宣告了乙個nsstring型別的例項 str, 並將其初始化init後賦值為@」abc」 第二行,將str的指標指向了乙個常量@」123」。 理論上講在第一行初始化的@」abc」沒有任何任何 指標指向了。 所以造成了記憶體洩露
然後第三行, 將str的引用計數-1
第四行輸出str的值 為123.
首先回答為什麼不會崩潰, 因為第三行的release 實際上是release了乙個常量@」123」 而作為 常量,其預設的引用計數值是很大的(100k+)
nslog(@」retaincount = %tu」,[@」123」 retaincount]); 最終的輸出值會是乙個很大很大的數。 所以單單乙個release是不會將其釋放掉的。
然後再回答這樣會不會造成記憶體洩露。
其實…………理論上講 會! 但是實際上,objective-c對nsstring型別有特殊照顧。所有的nsstring的引用計數器預設初始值 都會非常非常大。
三、autorelease自動釋放池基本使用
• autorelease方法的基本作用
• 1、給物件傳送一條autorelease訊息, 會將物件放到乙個自動釋放池中
• 2、當自動釋放池被銷毀時,會對池子裡面的所有物件做一次release操作
• 3、會返回物件本身
• 4、呼叫完autorelease方法後,物件的計數器不變
• autorelease的好處
• 不用再關心物件釋放的時間
• 不用再關心什麼時候呼叫release
• autorelease的使用注意
• 占用記憶體較大的物件不要隨便使用autorelease
• 占用記憶體較小的物件使用autorelease,沒有太大影響
• 自動釋放池:
• 在ios程式執行過程中,會建立無數個池子。這些池子都是以棧結構存在(先進後出)
• 當乙個物件呼叫autorelease方法時,會將這個物件放到棧頂的釋放池
• 自動釋放池的建立方式】
• ios 5.0前
nsautoreleasepool *pool = [[nsautoreleasepool alloc] init]; [pool release]; // [pool drain];
• ios 5.0 開始
@autoreleasepool
autoreleasepool 的 實現
autorelease
是一種支援引用計數的記憶體管理方式 它可以暫時的儲存某個物件(object),然後在記憶體池自己的排乾(drain)的時候對其中的每個 物件傳送release訊息 注意,這裡只是傳送release訊息,如果當時的引用計數(reference-counted)依然不為0,則該 物件依然不會被釋放。可以用該方法來儲存某個物件,也要注意儲存之後要釋放該物件。
2、為什麼會有autorelease?
oc的記憶體管理機制中比較重要的一條規律是:誰申請,誰釋放 考慮這種情況,如果乙個方法需要返回乙個新建的物件,該物件何時釋放? 方法內部是不會寫release來釋放物件的,因為這樣做會將物件立即釋放而返回乙個空物件;呼叫 者也不會主動釋放該物件的,因為呼叫者遵循「誰申請,誰釋放」的原則。那麼這個時候,就發 生了記憶體洩露。
不使用autorelease存在的問題
針對這種情況,objective-c的設計了autorelease,既能確保物件能正確釋放,又能返回有效的 物件。
3、autorelease是什麼原理?
autorelease實際上只是把對release的呼叫延遲了,對於每乙個autorelease,系統只是把該 object放入了當 前的autorelease pool中,當該pool被釋放時,該pool中的所有object會被呼叫 release。
4、autorelease何時釋放?
對於autorelease pool本身,會在如下兩個條件發生時候被釋放(詳細資訊請參見第5條) 1)手動釋放autorelease pool
2)runloop結束後自動釋放
對於autorelease pool內部的物件
在引用計數的retain == 0的時候釋放。release和autorelease pool 的 drain都會觸發retain– 事件。
5、autorelease釋放的具體原理是什麼?
要搞懂具體原理,則要先要搞清楚autorelease何時會建立。 我們的程式在main()呼叫的時候會自動呼叫乙個autorelease,然後在每乙個runloop, 系統會隱 式建立乙個autorelease pool,這樣所有的release pool會構成乙個象callstack一樣的乙個棧式 結構,在每乙個runloop結束時,當前棧頂的 autorelease pool(main()裡的autorelease)會被 銷毀,這樣這個pool裡的每個object會被release。
可以把autorelease pool理解成乙個類似父類與子類的關係,main()建立了父類,每個runloop自 動生成的或者開發者自定義的autorelease pool都會成為該父類的子類。當父類被釋放的時候, 沒有被釋放的子類也會被釋放,這樣所有子類中的物件也會收到release訊息。 那什麼是乙個runloop呢? 乙個ui事件,timer call, delegate call, 乙個滑鼠事件,鍵盤按 下(mac osx),或者iphone上的觸控事件,非同步http連線下後當接收完資料時,都會是乙個新的 runloop。 一般來說,訊息迴圈執行一次是毫秒級甚至微秒級的,因此autorelease的效率仍然是非常高的, 確實是乙個巧妙的設計。
autorelease的常見錯誤
• alloc之後呼叫了autorelease,又呼叫release
person *p = [[[person alloc] init] autorelease];
[p release];
• 連續呼叫多次autorelease
person *p = [[[[person alloc] init] autorelease] autorelease];
autorelease和release使用對比
• 使用release
book *book = [[book alloc] init];
[book release];
• 使用autorelease
book *book = [[[book alloc] init] autorelease];
// 不要再呼叫[book release];
autorelease的應用場合
• 一般可以為類新增乙個快速建立物件的類方法
+ (id)book
外界呼叫[book book]就可以獲得和使用新建的book物件,根本不用考慮在什麼時候釋放book物件
• 一般來說,除了alloc、new或copy之外的方法建立的物件都被宣告了autorelease
• 比如下面的物件都已經是autorelease的,不需要再release
nsnumber *n = [nsnumber numberwithint:100];
nsstring *s = [nsstring stringwithformat:@」jack」];
nsstring *s2 = @」rose」;
Oc 記憶體管理
1 對你自己擁有的物件負責,你只能釋放你擁有的物件 2 凡是你通過 retain alloc copy等手段獲得了所有者的物件,都必須在你不使用的時候來呼叫release autorelease等手段來釋放對他的所有權 3 在一定的 段內,對同乙個物件所作的copy alloc retain的操作次...
OC記憶體管理
1.記憶體管理原則 如果對乙個物件使用了alloc mutable copy retain,那麼你必須使用相應的release或者autorelease。2.管理範圍 任何繼承了nsobject 的物件,對其他基本資料型別 int char float double struct enum等 無效 ...
OC 記憶體管理
管理範圍 任何繼承nsobject的物件,對其他的基本資料型別無效。判斷物件要不要 的唯一依據就是計數器是否為0,若不為0則存在。所以對記憶體的管理就是對計數器的管理 1 retain 計數器 1,會返回物件本身 2 release 計數器 1 沒有返回值 3 retaincount 獲取當前的計數...