軟件運(yùn)行時(shí)會(huì)分配和使用設(shè)備的內(nèi)存資源香到,因此露筒,在軟件開發(fā)的過程中醇王,需要進(jìn)行內(nèi)存管理朵你,以保證高效、快速的分配內(nèi)存,并且在適當(dāng)?shù)臅r(shí)候釋放和回收內(nèi)存資源她渴。
一达址、Objective-C內(nèi)存管理的對(duì)象
IOS開發(fā)中,內(nèi)存中的對(duì)象主要有兩類惹骂,一類是值類型苏携,比如int、float对粪、struct等基本數(shù)據(jù)類型右冻,另一類是引用類型,也就是繼承自NSObject類的所有的OC對(duì)象著拭。前一種值類型不需要我們管理纱扭,后一種引用類型是需要我們管理內(nèi)存的,一旦管理不好儡遮,就會(huì)產(chǎn)生非常糟糕的后果乳蛾。
為什么值類型不需要管理,而引用類型需要管理呢鄙币?那是因?yàn)樗麄兎峙鋬?nèi)存方式不一樣肃叶。
值類型會(huì)被放入棧中,他們依次緊密排列十嘿,在內(nèi)存中占有一塊連續(xù)的內(nèi)存空間因惭,遵循先進(jìn)后出的原則。引用類型會(huì)被放到堆中绩衷,當(dāng)給對(duì)象分配內(nèi)存空間時(shí)蹦魔,會(huì)隨機(jī)的從內(nèi)存當(dāng)中開辟空間,對(duì)象與對(duì)象之間可能會(huì)留有不確定大小的空白空間咳燕,因此會(huì)產(chǎn)生很多內(nèi)存碎片勿决,需要我們管理。
棧內(nèi)存與堆內(nèi)存從性能上比較招盲,棧內(nèi)存要優(yōu)于堆內(nèi)存低缩,這是因?yàn)闂W裱冗M(jìn)后出的原則,因此當(dāng)數(shù)據(jù)量過大時(shí)曹货,存入棧會(huì)明顯的降低性能咆繁。因此,我們會(huì)把大量的數(shù)據(jù)存入堆中控乾,然后棧中存放堆的地址么介,當(dāng)需要調(diào)用數(shù)據(jù)時(shí)娜遵,就可以快速的通過棧內(nèi)的地址找到堆中的數(shù)據(jù)蜕衡。
值類型和引用類型之間是可以相互轉(zhuǎn)化的,把值類型轉(zhuǎn)化為引用類型的過程叫做裝箱,比如把int包裝為NSNumber慨仿,這個(gè)過程會(huì)增加程序的運(yùn)行時(shí)間久脯,降低性能。而把引用類型轉(zhuǎn)為值類型的過程叫做拆箱镰吆,比如把NSNumer轉(zhuǎn)為float帘撰,在拆箱的過程中,我們一定要注意數(shù)據(jù)原有的類型万皿,如果類型錯(cuò)誤摧找,可能導(dǎo)致拆箱失敗,因此會(huì)存在安全性的問題牢硅。手動(dòng)的拆箱和裝箱蹬耘,都會(huì)增加程序的運(yùn)行時(shí)間,降低代碼可讀性减余,影響性能综苔。
在IOS開發(fā)過程中,棧內(nèi)存中的值類型系統(tǒng)會(huì)自動(dòng)管理位岔,堆內(nèi)存中的引用類型是需要我們管理的如筛。每個(gè)OC對(duì)象內(nèi)部都專門有四個(gè)字節(jié)來存儲(chǔ)引用計(jì)數(shù)器,它是一個(gè)整數(shù)抒抬,表示對(duì)象被引用的次數(shù)杨刨,通過它可以判斷對(duì)象是否被回收,如果引用計(jì)數(shù)為0瞧剖,對(duì)象回收拭嫁,不為0不回收。當(dāng)對(duì)象執(zhí)行alloc抓于、new或者retain時(shí)做粤,引用計(jì)數(shù)加1,release時(shí)捉撮,引用計(jì)數(shù)減1怕品。
二、Objective-C管理內(nèi)存的方式
Objective-c中提供了兩種內(nèi)存管理機(jī)制MRC(Mannul Reference Counting)和ARC(Automatic Reference Counting)巾遭,分別提供對(duì)內(nèi)存的手動(dòng)和自動(dòng)管理肉康,來滿足不同的需求。MRC與ARC區(qū)別如下圖所示灼舍。
IOS 內(nèi)存管理
1.MRC(人工引用計(jì)數(shù))吼和,手動(dòng)管理內(nèi)存。
MRC模式下骑素,所有的對(duì)象都需要手動(dòng)的添加retain炫乓、release代碼來管理內(nèi)存。使用MRC,需要遵守誰創(chuàng)建末捣,誰回收的原則侠姑。也就是誰alloc,誰release箩做;誰retain莽红,誰release。
當(dāng)引用計(jì)數(shù)為0的時(shí)候邦邦,必須回收安吁,引用計(jì)數(shù)不為0,不能回收燃辖,如果引用計(jì)數(shù)為0柳畔,但是沒有回收,會(huì)造成內(nèi)存泄露郭赐。如果引用計(jì)數(shù)為0薪韩,繼續(xù)釋放,會(huì)造成野指針捌锭。為了避免出現(xiàn)野指針俘陷,我們?cè)卺尫诺臅r(shí)候,會(huì)先讓指針=nil观谦。
2.ARC(自動(dòng)引用計(jì)數(shù))拉盾,自動(dòng)管理內(nèi)存。
ARC是IOS5推出的新功能豁状,通過ARC捉偏,可以自動(dòng)的管理內(nèi)存。在ARC模式下泻红,只要沒有強(qiáng)指針(強(qiáng)引用)指向?qū)ο筘睬荩瑢?duì)象就會(huì)被釋放。在ARC模式下谊路,不允許使用retain讹躯、release、retainCount等方法缠劝。并且潮梯,如果使用dealloc方法時(shí),不允許調(diào)用[super dealloc]方法惨恭。
ARC模式下的property變量修飾詞為strong秉馏、weak,相當(dāng)于MRC模式下的retain脱羡、assign萝究。strong :代替retain母廷,缺省關(guān)鍵詞,代表強(qiáng)引用糊肤。weak:代替assign,聲明了一個(gè)可以自動(dòng)設(shè)置nil的弱引用氓鄙,但是比assign多一個(gè)功能馆揉,指針指向的地址被釋放之后,指針本身也會(huì)自動(dòng)被釋放抖拦。
三升酣、與內(nèi)存有關(guān)的修飾符
strong :強(qiáng)引用,ARC中使用态罪,與MRC中retain類似噩茄,使用之后,計(jì)數(shù)器+1复颈。
weak :弱引用 绩聘,ARC中使用,如果只想的對(duì)象被釋放了耗啦,其指向nil凿菩,可以有效的避免野指針,其引用計(jì)數(shù)為1帜讲。
readwrite : 可讀可寫特性衅谷,需要生成getter方法和setter方法時(shí)使用。
readonly : 只讀特性似将,只會(huì)生成getter方法 不會(huì)生成setter方法获黔,不希望屬性在類外改變。
assign :賦值特性在验,不涉及引用計(jì)數(shù)玷氏,弱引用,setter方法將傳入?yún)?shù)賦值給實(shí)例變量腋舌,僅設(shè)置變量時(shí)使用预茄。
retain :表示持有特性,setter方法將傳入?yún)?shù)先保留侦厚,再賦值耻陕,傳入?yún)?shù)的retaincount會(huì)+1。
copy :表示拷貝特性刨沦,setter方法將傳入對(duì)象復(fù)制一份诗宣,需要完全一份新的變量時(shí)。
nonatomic :非原子操作想诅,不加同步召庞,多線程訪問可提高性能岛心,但是線程不安全的。決定編譯器生成的setter getter是否是原子操作篮灼。
atomic :原子操作忘古,同步的,表示多線程安全诅诱,與nonatomic相反髓堪。
四、MRC與ARC混編
MRC與ARC理論上是不能兼容的娘荡,也就是你如果創(chuàng)建的項(xiàng)目是ARC模式的干旁,在你的代碼中是不能使用release,否則會(huì)出現(xiàn)內(nèi)存問題∨阢澹現(xiàn)在大部分程序都會(huì)選擇ARC的方式争群,但是很多第三方的框架是MRC模式,如果想把這些第三方的文件加到自己項(xiàng)目中大年,需要進(jìn)行標(biāo)識(shí)换薄,否則編譯的時(shí)候會(huì)出現(xiàn)錯(cuò)誤。
在ARC的項(xiàng)目中翔试,對(duì)MRC的文件可以添加編譯選項(xiàng)-fno-objc-arc的標(biāo)識(shí)专控;在MRC的項(xiàng)目中,對(duì)ARC的文件可以添加編譯選項(xiàng) -fobjc-arc的標(biāo)識(shí)遏餐。 步驟如下圖所示伦腐。
IOS 內(nèi)存管理
把MRC文件轉(zhuǎn)為ARC,實(shí)際上是去掉文件中的retain失都、release柏蘑,因此也通過下圖中方式完成。
原文出處:http://www.reibang.com/p/66b5d43b6ac4