OC中的內(nèi)存管理
alloc init 方式創(chuàng)建對(duì)象, 一般情況下在堆上上,使用完一定要釋放 手動(dòng)內(nèi)存管理 自動(dòng)內(nèi)存管理(自動(dòng)引用計(jì)數(shù)-ARC) 如何內(nèi)存管理方式切換到手動(dòng)內(nèi)存管理? 工程配置–>TARGETS->Build Setting-> 搜索 counting, 設(shè)置為NO
內(nèi)存管理中常用的方法
alloc init //1.alloc init //alloc: 為對(duì)象申請(qǐng)空間,把這塊空間全部初始化為0 //alloc申請(qǐng)的對(duì)象一般情況下都在堆空間,必須考慮釋放的問(wèn)題 //init 初始化這個(gè)對(duì)象 Dog *princess = [[Dog alloc] init]; dealloc release retain retainCount
引用計(jì)數(shù)這種內(nèi)存管理方式
//獲取對(duì)象被使用的次數(shù) NSLog(@”count=%lu”,princess.retainCount); //以后內(nèi)存管理中有問(wèn)題的 //retain: 讓對(duì)象引用次數(shù) 1 //retain的對(duì)象也要release [p release]; NSLog(@”count=%lu”,princess.retainCount); //釋放放在最后 //release作用: // 如果retainCount>1 說(shuō)明有多個(gè)人在使用這個(gè)對(duì)象,不會(huì)釋放,對(duì)象引用次數(shù)-1 // 如果retianCount==1 // 最后使用的”人”釋放這個(gè)對(duì)象 // 調(diào)用dealloc真正釋放對(duì)象 [princess release]; NSMutableString str = [[NSMutableString alloc] initWithString:@”的麻煩了看什么地方了開始免費(fèi)立刻馬上離開父母薩洛克沒(méi)放到里面是打發(fā)來(lái)看馬薩拉蒂方面撒地方可拉伸的佛羅倫薩地方了”]; //特別值得注意的問(wèn)題 // 最好千萬(wàn)不要在對(duì)象release之后使用對(duì)象 //什么是釋放: // 釋放是失去了這塊內(nèi)存的使用權(quán)(內(nèi)存還在) // 一旦釋放, 別人有可能使用這塊內(nèi)存 // 咱們?cè)谑褂玫木蜁?huì)出現(xiàn)問(wèn)題 //[princess show]; copy mutableCopy //問(wèn)題: // retain兩個(gè)指針, 只有一個(gè)對(duì)象 // copy復(fù)制這個(gè)對(duì)象 // 效果: 兩個(gè)指針指向不同的對(duì)象 // copy 返回不可變對(duì)象 // mutableCopy返回可變對(duì)象 NSMutableString pname = [name mutableCopy];
內(nèi)存管理原則:黃金法則 如果你對(duì)一個(gè)對(duì)象使用了 alloc,retain,copy/mutableCopy, 使用完這個(gè)對(duì)象之后需要調(diào)用對(duì)應(yīng)的realese或autorelease 代碼中alloc和release成對(duì)出現(xiàn)的retain和release也是成對(duì)出現(xiàn)的
代碼中出現(xiàn)的各種內(nèi)存管理情況
(0)如果在方法內(nèi)部定義了一個(gè)對(duì)象指針,指向了alloc申請(qǐng)的對(duì)象 需要在方法結(jié)束前釋放這個(gè)對(duì)象
init中為對(duì)象指針(類的實(shí)例變量)的申請(qǐng)對(duì)象
需要在dealloc方法中釋放 (重點(diǎn)) //需求: 創(chuàng)建車的同時(shí)添加引擎 -(id)init { if(self = [super init]) { //考慮到釋放問(wèn)題 //類中對(duì)象指針一般在init中申請(qǐng)對(duì)象 // 在dealloc中釋放對(duì)象 _e 大專欄 ?內(nèi)存管理ngine = [[Engine alloc] init]; //NSString *str = [[NSString alloc] init]; //[str release]; } return self; } -(void)dealloc { NSLog(@”Car dealloc”); [_engine release]; //這句放在最后 [super dealloc]; }
對(duì)象指針的setter方法
//_engine實(shí)現(xiàn)設(shè)置方法 -(void)setEngine:(Engine *)engine { //以前的寫法 //_engine = engine; //傳入的指針和保存指針相同,返回即可 if(_engine == engine) { return; } //舊的對(duì)象不用了, 立即釋放 [_engine release]; //多一個(gè)指針指向engine對(duì)象 //引用次數(shù) 1,調(diào)用retian方法 _engine = [engine retain]; }
對(duì)象指針的getter方法
//_engine實(shí)現(xiàn)獲取方法 -(Engine *)engine { //以前的實(shí)現(xiàn) //return _engine; //retain: 返回的對(duì)象類外的指針指向, 多了一個(gè)使用, 引用 1 // autorelease誰(shuí)使用,誰(shuí)釋放 // 不能用release, 立即使用 return [[_engine retain] autorelease]; }
各種實(shí)例變量的property (重點(diǎn))
//使用property實(shí)例變量添加getter和setter // 一般情況, NSString 使用copy作為屬性修飾符 //copy, 把傳入的字符串拷貝一個(gè)份新的 //字符串,字典,數(shù)組用copy最好 @property (copy) NSString type; //assign表示直接賦值, 不retain也不copy // 默認(rèn)是assign, assgin可以不寫 //@property (assign) float price; @property float price; //retain表示實(shí)現(xiàn)的setter中添加retain,getter也會(huì)添加retain @property (retain) Engine engine;
//代理設(shè)計(jì)模式中 // 代理的屬性修飾符必須是assgin,不能是retain,否則會(huì)引起無(wú)法釋放的問(wèn)題 @property (assign) id delegate;
取消線程保護(hù) nonautomic
//nonatomic取消多線程保護(hù) //1.什么是多線程(多任務(wù)) // 迅雷下載(界面響應(yīng)用戶點(diǎn)擊,下載數(shù)據(jù)) //2.為啥要加這一句啊 // 多線程保護(hù)比較耗時(shí), 取消提供代碼速度 @property (nonatomic) float speed;
類方法創(chuàng)建對(duì)象如何寫?
//類方法創(chuàng)建的對(duì)象無(wú)需釋放, 也不能釋放 創(chuàng)建對(duì)象的方法,類方法 (id)car { //干兩件事情 Car *car = [[Car alloc] init]; //if(car) //{ //設(shè)置car的屬性 //} //alloc和autorelease對(duì)應(yīng)起來(lái) return [car autorelease]; }
數(shù)組中的添加對(duì)象內(nèi)存管理 NSArray
//數(shù)組被釋放的時(shí)候會(huì)給數(shù)組中每個(gè)對(duì)象發(fā)送release [array release];
字符串的內(nèi)存管理
// 特點(diǎn): 特立獨(dú)行,有性格 //字符串常量的引用數(shù)是極大值,不需要釋放 //總結(jié): 以alloc創(chuàng)建的字符串最后使用release釋放 字符串常量和以類方法創(chuàng)建的字符串不需要釋放
來(lái)源:https://www./content-3-625301.html
|