Objective-C 記憶體管理

來源:互聯網
上載者:User

標籤:

概述

開發的過程中,很多程式員都不會注意管理對象或者變數的記憶體,導致系統或者應用運行一段時間,就很慢了,或者崩潰。下面我們一起聊聊編程過程中的記憶體是如何進行管理的。

記憶體管理組件含那些方面?

有效記憶體管理,通常包含兩方面內容:

  記憶體配置:當程式建立對象時需要為對象分配記憶體。採用合理的設計,盡量的減少對象的建立,並減少對建立過程中的記憶體開銷。

  記憶體回收:當程式不再需要對象時,系統必須及時回收這些對象所佔用的記憶體,以便程式可以再次使用這些記憶體。

 

iOS 5 之前,iOS開發人員,需要話費精力去處理記憶體回收相關的問題。iOS 5 之後,引入了心的特性:自動引用技術(ARC)。通過 ARC ,程式員可以不需要關注記憶體回收這塊內容,可以大大的提高開發的效率。

  Objective-C 記憶體回收機制有以下方式

  • 手動引用計數 MRC
  • 自動引用技術 ARC
手動引用計數

目前建立的項目預設都是ARC的,如何可以將項目改為 MRC 模式呢?

建立項目,開啟項目的配置介面,選擇 Target -> Buld Setting -> 搜尋 automatic reference , 設定

將自動引用計數設定為NO,就可以手動引用計數了。

 

  Objective-C 採用來一種被稱為引用計數的計數來跟蹤對象的狀態:每個對象都有一個與之關聯的整數,這個整數被稱為引用計數器。正常情況下,當一段代碼需要訪問某個對象時,該對象的引用計數加1;當這段代碼不在訪問改對象時,改對象的引用計數減1,表示這段代碼不在訪問該對象。當對象的引用計數為0的時候,表示程式已經不在需要該對象,系統就會回收改對象所佔用的記憶體。

  系統在銷毀該對象之前,會自動調用改對象的 delloc 方法來執行一些回收操作。

  當對象唄銷毀之後,此時該對象已經不再存在;如果有一個指標指向這個被銷毀的對象,這個指標酒杯稱為懸null 指標,也稱為野指標,殭屍指標,調用該指標指向對象的方法時,程式往往會出現未知的結果,甚至導致程式崩潰。

 

在手動引用計數中,改變對象的引用計數的方式如下:

  • 當程式調用方法名以 alloc、new、copy、mutableCopy 開頭的方法來建立對象時,該對象的引用計數加1.
  • 當程式調用對象的 retain 方法時,該對象的引用計數加1.
  • 當程式調用對象的 release 方式時,該對象的引用計數減1.

NSObject 中提供了有關引用計數的方法:

  • retain: 引用計數+1
  • release:引用計數-1
  • autorelease:不改變該對象的引用計數器的值,只是將對象添加到自懂釋放池中。
  • retainCount:返回該對象的引用計數的值。

看看測試代碼:

 1 // 2 //  Item.m 3 //  MRC 4 // 5 //  Created by 萬齊鶼 on 15/7/27. 6 //  Copyright (c) 2015年 萬齊鶼. All rights reserved. 7 // 8  9 #import "Item.h"10 11 @implementation Item12 13 - (instancetype)init14 {15     self = [super init];16     if (self) {17         NSLog(@"init方法中,引用計數為:%ld", self.retainCount);18     }19     return self;20 }21 22 -(void)dealloc23 {24     NSLog(@"調用銷毀的方法");25     [super dealloc];26 }27 28 @end
////  main.m//  MRC////  Created by 萬齊鶼 on 15/7/27.//  Copyright (c) 2015年 萬齊鶼. All rights reserved.//#import <Foundation/Foundation.h>#import "Item.h"int main(int argc, const char * argv[]) {    @autoreleasepool {        // insert code here...        Item * item = [[Item alloc] init]; // 引用計數1        NSLog(@"%ld", item.retainCount);        [item retain]; // 引用計數2        NSLog(@"%ld", item.retainCount);        [item retain]; // 引用計數3        NSLog(@"%ld", item.retainCount);        [item release]; // 引用計數2        NSLog(@"%ld", item.retainCount);        [item retain]; // 引用計數3        NSLog(@"%ld", item.retainCount);        [item release]; // 引用計數2        NSLog(@"%ld", item.retainCount);        [item release]; // 引用計數1        NSLog(@"%ld", item.retainCount);        [item release]; // 引用計數0    }    return 0;}

啟動並執行結果:

 

 

手工記憶體管理規則的總結

  • 如果需要保持一個對象不被銷毀,可以使用 retain 。在使用完對象後,需要使用 release 進行釋放。
  • 給對象發送 release 訊息並不會銷毀這個對象,只當這個對象的引用計數減至0時,對象才會被銷毀。然後系統會發送 dealloc 訊息給這個對象用語釋放對象。
  • 對使用了 retain 或者 copy、mutableCopy、alloc 或 new 方法的任何對象,以及具有 retain 和 copy 特性的屬性進行釋放,需要覆蓋 dealloc 方法,使得對象被釋放的時候能夠釋放這些案例變數。
  • 在自動釋放池被清空時也會為自動釋放的對象做些事情。系統每次都會在自動釋放池被釋放時發送 release 訊息給池中的每個對象。如果池中的對象引用計數降為0,系統會發送 dealloc 訊息銷毀這個對象。
  • 如果在方法中不再需要用到這個對象,但需要將其返回,可以給這個對象發送 autolease 訊息用意標記這個對象延遲釋放。autolease 訊息並不會影響到對象的引用計數。
  • 當應用終止時,記憶體中的所有對象都會被釋放,不論它們釋放在制動釋放池中。
  • 當開發應用程式時,隨著應用程式的運行,自動釋放池會被建立和清空。在這種情況下,如果要時自動釋放池被清空後自動釋放的對象還能夠存在,對象需要使用 retain 方法,只要這些對象的引用計數大於發送 autorelease 訊息的資料,就能搞在池清理後生存下來。 

Objective-C 記憶體管理

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.