------<a target="blank">java培訓、Android培訓、iOS培訓、.Net培訓</a>、期待與您交流! -------
內存管理
單個對象內存管理
1. 野指針錯誤:
訪問了一塊壞的內存
2. 僵尸對象:
如果一個對象已經被釋放,這個對象被稱為僵尸對象
3. 空指針:
沒有指向任何東西的指針,給空指針發送消息不會報錯
4. nil和NULL的區別
nil 對象指針
NULL 類對象指針
5. 避免使用僵尸對象的方法:
對象釋放了以后,給對象賦值為nil
6. 單個對象的內存泄露
情況1: 創建完成,使用之后,沒有release
情況2: 沒有遵守內存管理原則
Dog *d = [[Dog alloc] init]
[d retain];
情況3: 不當的使用了nil
Dog *d = [[Dog alloc] init]
d = nil;
情況4: 在方法中對傳入的對象進行了retain
Dog *d = [[Dog alloc] init]
[d compareColorWithOther: d];
基本數據類型set方法的寫法 直接賦值
-(void)setSpeed:(int)speed{ _speed = speed;}
對于對象作為另外一個類的實例變量
-(void)setDog:(Dog *)dog{if(_dog!=dog){ //先判斷是不是原來的對象[_dog release]; //不是原來的對象做一次release,_dog = [dog retain];}}
@PRoperty 參數
格式:@property (參數1,參數2) 數據類型 方法名
1.是否要生成set方法
readwrite : 同時生成setter和getter的聲明、實現
readonly :只會生成getter的聲明和實現
2.多線程管理
nonatomic :性能高(一般用這個)
atomic :性能低(默認)
3.set管理相關參數
retain :release舊值,return新值(適用于oc對象類型)
assign : 直接賦值(默認,適用于非OC對象)
-(void)setCar:(Car *)car{
_car =car;
}
(2) retain release舊值,再retain新值
在一個類中有關聯其他對象的時候,這個對象的 @property(nonatomic,assign) 數據類型 方法名
-(void)setCar:(Car *)car{if(_car!=car){ //先判斷是不是原來的對象[_car release]; //不是原來的對象做一次release,_car = [car retain];}}
readonly :只讀,只會生成getter的聲明和實現
readwrite:默認的,同時生成setter和getter的聲明和實現
(4)多線程管理
@property(nonatomic,assign) 數據類型 方法名
高性能,一般使用nonatomic
(5) set和get方法的名稱
修改set和get方法的名稱,主要用于布爾類型。因為返回布爾類型的方法名一般以is開頭,修改名稱一般用 在布爾類型中的getter
//替換set方法名稱 @property(nonatomic,assign ,setter= isVip:) //替換get方法名稱 @property(nonatomic,assign ,getter = isVip)//替換set,get方法名稱 @property(nonatomic,assign ,setter=isVip,getter = isVip:)
循環retain問題
會導致兩個對象都會內存泄露
防止方法:
1) 讓某一個對象多釋放一次(注意順序)
2) 推薦方法: 一端使用assign 一端使用retain
Dog.h#import <Foundation/Foundation.h>//#import "Person.h"@class Person;@interface Dog : NSObject//狗有個主人@property (nonatomic,retain) Person *owner;//這里用retain@endDog.m#import "Dog.h"#import "Person.h"@implementation Dog- (void)dealloc{ [_owner release]; // NSLog(@"Dog dealloc"); [super dealloc];}@endPerson.h#import <Foundation/Foundation.h>//#import "Dog.h"@class Dog;@interface Person : NSObject//人擁有一條狗@property (nonatomic,assign) Dog *dog;//這里用assign@endPerson.m#import "Person.h"#import "Dog.h"@implementation Person- (void)dealloc{ // [_dog release]; //nil這里不在需要 NSLog(@"Person dealloc"); [super dealloc];}@endmain.m #import <Foundation/Foundation.h>#import "Dog.h"#import "Person.h"int main(int argc, const char * argv[]) { @autoreleasepool { Person *p = [Person new]; //1 Dog *d = [Dog new]; //1 //人有一條狗 p.dog = d; // d 1 d.owner = p; // p 2 [p release]; //0 [d release]; // // [d release]; // [p release]; } return 0;}
類方法不需要管理內存
autorelease基本使用
一個對象調用autorelease,將這個對象放到位于棧頂得的釋放池
@autoreleasepool
{ //
}
概念介紹: 一種支持引用計數器的內存管理方式,可以暫時保存某個對象,然后再內存池自己的排干的時候對其中的每個對象發送release消息
好處: 不用擔心對象釋放時間,也不用擔心什么時候調用release
原理:
autorelease實質上只是把對release的調用延遲了,對于每一個autorelease,該Object放入了當前的Autoreleasepool中,當該pool釋放時,該pool中的所有Object都會被調用release;
自動釋放池: 特殊的棧結構(數據結構),和內存的棧區結構不同
特點: 對象可以加入到自動釋放池中,自動釋放池結束的時候,會給釋放池中的每個對象發送一條release消息
使用:
1)自動創建釋放池
autoreleasepool{
}
2)加入自動釋放池,
在自動釋放池中
[對象 autorelease]
加入到自動釋放池中以后,引用計數器不會變化
基本用法總結
1.會將對象放到一個自動釋放池中
2.當自動釋放池被銷毀時,會對尺子里的所有對象做一次release操作
3.會返回對象本身
4.調用完autorelease方法后,對象的計數器不變。
int main(int argc, const char * argv[]) { //1 創建自動釋放池 Person *p = [Person new]; // p 1 @autoreleasepool {//自動釋放池開始 [p run]; NSLog(@"%lu",p.retainCount); // 1 // [p autorelease] 把對象p加入到自動釋放池中 // 注意:加入到自動釋放池中以后, 引用計數不會變化 [p autorelease]; //加入自動釋放池, NSLog(@"%lu",p.retainCount); // 1 [p run]; }//自動釋放池結束 [p release]; [p run]; return 0;}
注意及錯誤用法:
1)并不是放到自動釋放池中的代碼產生的對象就會自動釋放,如果需要釋放,必須自動加入到自動釋放池
2)如果對象調用了autorelease但是調用autorelease的時候,沒有在任何一個自動釋放池中,此時該對象也不會被加入到自動釋放池
3)我們只需要在自動釋放池代碼塊中調用autorelease就可以把對象加入到自動釋放池
4)內存較大盡量不要使用autorelease
自動釋放池嵌套使用
為什么內存管理只管理內存對象?
堆中內存不連續,無法自動釋放!
我們如何對內存對象進行管理!
通過操作對象的引用計數器
autorelease的應用場景
經常用來在類方法中快速創建一個對象
1)判斷是否是ARC機制
查看項目信息,不能使用retain release和autorelease,retainCount ,不能調用[super dealloc]
2)使用
正常創建對象,不用手動釋放對象
ARC下單對象內存管理
ARC機制下,對象沒有被強指針指向,對象會立即釋放空間
(兩個下劃線)__strong 修飾的指針是強指針,可以不寫
__weak 修飾的指針是弱指針
1) 強指針指向了其他內容,對于對象來說就沒有強指針指向了
2) 弱指針賦值為nil
ARC下多對象的內存管理
ARC機制下不能使用retain 應該使用strong 和 weak
ARC下循環引用問題
循環引用時一端使用strong , 一端使用weak.
ARC下set方法內存和@property參數
原子性/讀寫 和MRC下一樣
MRC ARC
assign assign 適用于非oc對象
retain strong(強指針) OC的其他對象 weak (成員變量是弱指針適用于oc對象)
copy copy
ARC使用特點及注意事項
特點:
1) 不允許調用retain release、retainCount
2) 允許重寫dealloc,但是不能調用[super dealloc]
注意事項:
1)ARC中,只要弱指針對象不存在,直接把弱指針清空(賦值nil)操作
2)__weak Person *p = [Person new]
弱指針指向空間銷毀過程: (1)釋放對象空間 (2)指針賦值nil
MRC轉換為ARC
edit->Refactor->convert to Objective-C ARC…簡單代碼
ARC兼容非ARC的類
轉變為非ARC -fno-objc-arc
轉變為ARC的 -f-objc-arc
新聞熱點
疑難解答