OC----内存管理
生活随笔
收集整理的這篇文章主要介紹了
OC----内存管理
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
任何繼承了NSObject的對象,都需要內存管理, 但是對基本數據類型無效(不需要釋放) 原理: 每個對象內部都保存了一個與之相關聯的整數,稱為引用計數器 當使用alloc、new或者copy創建一個對象時,對象的引用計數器被設置為1 給對象發送一條retain消息,可以使引用計數器值+1 給對象發送一條release消息,可以使引用計數器值-1 當一個對象的引用計數器值為0時,那么它將被銷毀,其占用的內存被系統回收,OC也會自動向對象發送一條dealloc消息。一般會重寫dealloc方法,在這里釋放相關資源。一定不要直接調用dealloc方法。 可以給對象發送retainCount消息獲得當前的引用計數器值 向對象發送某個消息,相當于調用某個方法。 內存管理原則: 誰創建,誰釋放(“誰污染,誰治理”)。如果通過alloc、new或(mutable)copy來創建一個對象,那么你必須調用release或autorelease。換句話說,不是你創建的,就不用你去釋放。 一般來說,除了alloc、new或copy之外的方法創建的對象都被聲明了autorelease 誰retain,誰release。只要你調用了retain,無論這個對象誰如何生成的,你都要調用release 如果在某個對象方法中retain了另一個對象,需要在這個對象釋放的時候同時釋放retain的那個對象。 如果想要retain對象新的成員變量,先釋放掉舊的成員變量;在釋放掉舊的成員變量前要先判斷新傳遞進來的成員變量與原來的成員變量是否相同,如果不同則釋放掉舊的成員變量,如果相同則不release舊的成員變量,也不進行retain。 @property內存管理新特性: @property一般幫我們自動生成的setter方法是很簡單的方法,不能實現內存管理,例如: -(void)setBook:(Book*) book{_book=book;
}
?
所以我們一般需要自己去實現book的setter方法,例如: -(void)setBook:(Book *)book{if(_book!=book){[_book release];_book=[book retain];} }?
假如我們在某個類里要使用很多個@property 語句去使用類的屬性的時候,如果還要自己在.m文件中去寫setter方法會很麻煩,所以我們可以這么寫: @property (retain)Book* book; @property (retain)Card*?card; 這里的retain代表:release舊的值,retain新的值 這樣相當于我們在.m文件中實現了帶有內存管理的setter方法(即上面的代碼) @property的其他參數:默認是(readwrite)屬性,同時生成get和set方法 @property(assign)int age;這句跟@property int age等價,@property默認就是assign參數的 @property(readonly)int age;這句表示age是一個只讀變量,表示只生成get方法 @property 格式:@property(參數1,參數2) 類型 名字; 參數可有可無,比如: @property int age; @property (nonatomic,retain)UIButton* btn; 參數主要分為3類: 讀寫屬性:readwrite/readonly setter處理:assign/retain/copy 原子性:atomic/nonatomic? @property屬性默認為atomic,提供多線程安全- 在多線程環境下,原子操作是必要的,否則就有可能引起錯誤的結果
- 加了atomic,setter/getter是一個原子操作。如果有多個線程同時調用setter的話,不會出現某一個線程執行setter全部語句之前,另一個線程開始執行setter的情況,相當于函數頭尾加了鎖一樣
- nonatomic表示禁止多線程,變量保護,提高性能
- atomic是OC使用的一種線程保護技術,防止在寫入未完成的時候被另外一個線程讀取,造成數據錯誤。而這種機制是耗費系統資源的,所以在iphone這種小型設備上,如果沒有使用多線程間的通訊編程,那么nonatomic是一個非常好的選擇
- 如果不需要多線程支持的話,用nonatomic就夠了,另外由于不涉及鎖操作,所以它執行相對快點
- 自動釋放池是OC里面的之中內存自動回收機制,一般可以將一些(臨時)變量添加到自動釋放池中,統一回收釋放
- 當自動釋放池銷毀時,池里面的所有對象都會調用一次release方法
- OC對象只需要發送一條autorelease消息,就會把這個對象添加到最近的自動釋放池中(棧頂的釋放池)
- autorelease實際上只是把對release的調用延遲了(相當于延遲回收對象),對于每一次autorelease,系統只是把該對象放入了當前的autorelease pool中,當該pool被釋放時,該pool中的所有對象會被調用renlease?
?
靜態方法不需要自己釋放內存,我們在開發中會經常用到靜態方法,因為我們在實現靜態方法時,會把變量放到autorelease中這樣就不用我們自己去釋放內存了 另外:靜態方法不能訪問對象的成員變量 autorelease pool注意:- 在ARC下,不能使用[[NSAutoreleasePool alloc] init],而應當使用@autoreleasepool
- 不要把大量循環操作放到同一個NSAutoreleasePool之間,這樣會造成內存峰值的上升
- 盡量避免對大內存使用該方法,對于這種延遲釋放機制,還是盡量少用
- sdk中一般利用靜態方法創建并返回的對象都是已經autorelease的,不需要再進行release操作,如[NSNumber numberWithInt:10];返回的對象是不需要再release的。但是通過[[NSNumber alloc] initWithInt:10]創建的對象需要release
轉載于:https://www.cnblogs.com/hqzxbb/p/4383749.html
總結
以上是生活随笔為你收集整理的OC----内存管理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux部署的java应用,浏览器访问
- 下一篇: 深入浅出Docker(三):Docker