国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > iOS > 正文

ios內存管理

2019-11-06 09:57:17
字體:
來源:轉載
供稿:網友

1.堆和棧的區別 管理方式: 對于棧來講,是由編譯器自動管理,無需我們手工控制; 對于堆來說,釋放工作由程序員控制,容易產生memory leak。

申請大小:? 棧:在Windows下,棧是向低地址擴展的數據結構,是一塊連續的內存的區域。這句話的意思是棧頂的地址和棧的最大容量是系統 預先規定好的,在WINDOWS下,棧的大小是2M(也有的說是1M,總之是一個編譯時就確定的常數),如果申請的空間超過棧的剩余空間時,將提示 overflow。因此,能從棧獲得的空間較小。 ?堆:堆是向高地址擴展的數據結構,是不連續的內存區域。這是由于系統是用鏈表來存儲的空閑內存地 址的,自然是不連續的,而鏈表的遍歷方向是由低地址向高地址。堆的大小受限于計算機系統中有效的虛擬內存。由此可見,堆獲得的空間比較靈活,也比較大。 ? 碎片問題: 對于堆來講,頻繁的new/delete勢必會造成內存空間的不連續,從而造成大量的碎片,使程序效率降低。 對于棧來講,則不會存在這個 問題,因為棧是先進后出的隊列,他們是如此的一一對應,以至于永遠都不可能有一個內存塊從棧中間彈出

分配方式: 堆都是動態分配的,沒有靜態分配的堆。 棧有2種分配方式:靜態分配和動態分配。靜態分配是編譯器完成的,比如局部變量的分配。動態分配由 alloca函數進行分配,但是棧的動態分配和堆是不同的,他的動態分配是由編譯器進行釋放,無需我們手工實現。

分配效率: 棧是機器系統提供的數據結構,計算機會在底層對棧提供支持:分配專門的寄存器存放棧的地址,壓棧出棧都有專門的指令執行,這就決定了棧的 效率比較高。 堆則是C/C++函數庫提供的,它的機制是很復雜的。

2.內存管理原則是什么? 1. 誰創建,誰釋放(類似于“誰污染,誰治理”)。如果你通過alloc、new或copy來創建一個對象,那么你必須調用release或autorelease。換句話說,不是你創建的,就不用你去釋放。 例如,你在一個函數中alloc生成了一個對象,且這個對象只在這個函數中被使用,那么你必須在這個函數中調用release或autorelease。如果你在一個class的某個方法中alloc一個成員對象,且沒有調用autorelease,那么你需要在這個類的dealloc方法中調用release;如果調用了autorelease,那么在dealloc方法中什么都不需要做。 2. 除了alloc、new或copy之外的方法創建的對象都被聲明了autorelease。 3. 誰retain,誰release。只要你調用了retain,無論這個對象是如何生成的,你都要調用release。有時候你的代碼中明明沒有retain,可是系統會在默認實現中加入retain。

3.談一談自動釋放池

自動釋放池(Autorelease pool)是OC的一種內存自動回收機制,可以將一些臨時變量通過自動釋放池來回收統一釋放.自動釋放池本事銷毀的時候,池子里面所有的對象都會做一次release操作. 自動釋放池并不包含實際的對象本身,僅僅是對池釋放的時候要釋放的對象的引用,通過像當前的自動釋放池發送一條autorelease消息,就可以將一個對象添加到其中,以便以后釋放。 Cocoa應用程序中的每個線程都會維護一個自己的NSAutoreleasePool對象的堆棧。當一個線程終止時,它會自動地釋放所有與自身相關的自動釋放池。在基于application Kit的應用程序中,自動釋放池會在程序的主線程中被自動創建和銷毀,所以,您的代碼通常無需處理它們。但是,如果您在Application Kit的主線程之外發起Cocoa調用,則您需要創建自己的自動釋放池。如果您正在編寫一個Foundation應用程序,或者如果您拆分了一個線程,則是屬于這種情況。

4.什么是強指針,什么是弱指針? 強指針在當進行對象地址的賦值操作時會保留新值并釋放舊值,當其退出指針作用域時釋放。而弱指針則類似于手動內存管理時的指針,它僅僅是一個指針而已,不做額外的保留和釋放,在對象被回收時會自動置為nil。在程序中使用__strong關鍵字指定強指針,使用__weak關鍵字指定弱指針,默認為強指針。

if (someCondition){ NSMutableArray* stringArray = [NSMutableArray arrayWithObjects:@"A", @"B", @"C", nil]; id firstObj = [stringArray objectAtIndex:0]; [stringArray removeObjectAtIndex:0]; NSLog(@"%@", firstObj);}12345671234567

if語句塊的第一行代碼創建了一個數組,其中包含三個字符串對象,然后將其地址賦值給stringArray。第二行將數組的首元素地址賦值給firstObj,即指向字符串@”A”。第三行將數組首元素移出數組。第四行打印firstObj的描述信息。最后退出if語句塊。

在未開啟ARC時,由于元素在被移出數組時會被數組釋放,所以在調用NSLog函數時@”A”已經被回收,firstObj指向的是一個無效的地址(野指針、僵尸),這會導致程序崩潰。

而當開啟了ARC時,上述代碼就是正確的。當執行到第二行時,stringArray和firstObj均為強指針(默認為強指針),分別保留數組和@”A”,此時@”A”的所有者為數組和firstObj。到第三行,@”A”的所有者為firstObj,未被回收,所以NSLog語句沒有問題。最后退出if語句塊時,stringArray和firstObj退出作用域,分別釋放并回收數組和@”A”。

當然,你可以在定義stringArray和firstObj時指定__strong關鍵字:

[plain] view plaincopy__strong NSMutableArray* stringArray = [NSMutableArray arrayWithObjects:@"A", @"B", @"C", nil];__strong id firstObj = [stringArray objectAtIndex:0];123123

不過由于默認為強指針,所以__strong關鍵字是可以忽略的。

由于強指針會一直保留著對象,所以當你確實需要將其釋放時,需要手動將強指針賦值為nil,否則對象一直不會被回收,會導致系統內存資源不足。

再來說說弱指針。請看如下代碼:

[plain] view plaincopyNSString* strongPtr = [[NSString alloc] initWithCString:"A" encoding:NSUTF8StringEncoding];__weak NSString* weakPtr = strongPtr;NSLog(@"%@", weakPtr);strongPtr = nil;NSLog(@"%@", weakPtr);double delayInSeconds = 3.0;dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ NSLog(@"After 3 seconds: %@", weakPtr);});123456789101112123456789101112

由于firstObj為弱指針,前兩個NSLog輸出為A,而最后一個則為(null)。這說明當對象被回收時,所有指向該對象的弱指針均會被置為nil,但這需要時間。

讀到這里,你應該知道下面的代碼有什么問題了吧:

[plain] view plaincopy__weak NSArray* array = [[NSArray alloc] initWithObjects:@"Puzhi Li", nil];NSLog(@"%@", array);123123

當啟用了ARC之后,(基本上)不會出現內存泄漏、使用野指針、訪問僵尸對象的情況 。

5.多次調用對象的autorelease方法會導致什么問題? 多次將地址存到自動釋放池中,導致野指針異常


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 图片| 乌兰浩特市| 寻乌县| 桐庐县| 兰溪市| 临汾市| 含山县| 淄博市| 乡宁县| 清水河县| 自治县| 鹿泉市| 靖边县| 芒康县| 盐亭县| 梓潼县| 定州市| 临澧县| 禹城市| 轮台县| 屏边| 博乐市| 洪泽县| 柘城县| 新民市| 乐安县| 南华县| 洱源县| 中山市| 遂宁市| 德清县| 西林县| 获嘉县| 中牟县| 建始县| 罗源县| 临沭县| 德安县| 马关县| 教育| 克什克腾旗|