原文地址:http://www.reibang.com/p/66b5d43b6ac4
軟件運(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弥臼,需要遵守誰(shuí)創(chuàng)建,誰(shuí)回收的原則根灯。也就是誰(shuí)alloc径缅,誰(shuí)release;誰(shuí)retain烙肺,誰(shuí)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相反虏两。