鍍金池/ 教程/ C/ Objective-C 內(nèi)存管理
Objective-C 多態(tài)性
Objective-C 預處理器
Objective-C for循環(huán)
Objective-C 開發(fā)環(huán)境(安裝配置)
Obj-C Foundation/基礎框架
Objective-C 指針運算
Objective-C 循環(huán)
Objective-C 錯誤處理
Objective-C while循環(huán)
Objective-C if語句
Objective-C do...while循環(huán)
Objective-C教程
Objective-C 嵌套switch語句
Objective-C 函數(shù)按值調(diào)用
Objective-C 常量
Objective-C 運算符
Objective-C 數(shù)據(jù)類型
Objective-C 邏輯運算符
Objective-C 數(shù)組作為函數(shù)參數(shù)傳遞
Objective-C struct/結(jié)構(gòu)
Objective-C 嵌套循環(huán)
Objective-C 函數(shù)引用調(diào)用
Objective-C 日志處理
Objective-C 數(shù)據(jù)存儲
Objective-C 教程首頁
Objective-C 擴展
Objective-C 異常處理
Objective-C 類型轉(zhuǎn)換
Objective-C 嵌套 if 語句
Objective-C typedef
Objective-C 決策
Objective-C 指針的數(shù)組
Objective-C Protocols/協(xié)議
Objective-C 日期和時間
Objective-C 指針
Objective-C 內(nèi)存管理
命令行參數(shù)
Objective-C NSString/字符串
Objective-C 動態(tài)綁定
Objective-C 復合對象
Objective-C Arrays/數(shù)組
Objective-C 位運算符
Objective-C 指向指針的指針
Objective-C 從函數(shù)返回數(shù)組
Objective-C Posing/冒充
Objective-C Categories/類別
Objective-C 文件處理
Objective-C 賦值運算符
Objective-C 函數(shù)返回指針
Objective-C if...else 語句
Objective-C switch語句
Objective-C URL加載系統(tǒng)
Objective-C 算術(shù)運算符
Objective-C Numbers/數(shù)字
Objective-C語言程序結(jié)構(gòu)
Objective-C 快速枚舉
Objective-C 基本語法
Objective-C 類&對象
Objective-C 變量
Objective-C 關(guān)系運算符
Objective-C 塊
Objective-C break語句
Objective-C continue語句
Objective-C 語言概述
Objective C 文本和字符串
Objective-C 函數(shù)
Objective-C 傳遞函數(shù)的指針
Objective-C 數(shù)組的指針
Objective-C 多維數(shù)組
Objective-C 繼承
Objective-C 數(shù)據(jù)封裝

Objective-C 內(nèi)存管理

內(nèi)存管理是任何編程語言中最重要的過程之一。它是一個過程,通過該對象的內(nèi)存時,需要時分配,當不再需要時釋放。

管理對象的內(nèi)存性能是一個問題,如果一個應用程序沒有免費的不需要的對象,其內(nèi)存占用量的增長和性能將受到影響。

Objective-C的內(nèi)存管理技術(shù)大致可分為兩類。

  • “手動保留釋放”或MRR

  • “自動引用計數(shù)”或ARC

“手動保留釋放”或MRR

在 MRR中,我們明確地管理內(nèi)存,在我們自己的跟蹤對象。這是使用一種模式,被稱為引用計數(shù),基礎類NSObject 提供配合運行環(huán)境。

MRR 和 ARC 之間的唯一區(qū)別是,保留和釋放處理前手動而隨后自動處理。

下圖表示如何在Objective-C 內(nèi)存管理工作的一個例子。

Objective-C Memory management

在上圖中所示的A類對象的存儲生命周期。正如可以看到,如下圖所示的對象保留計數(shù),當保留計數(shù)的對象變?yōu)?的,對象是完全釋放,其它對象使用的內(nèi)存被釋放。

A類對象第一次被創(chuàng)建,使用分配/ NSObject的init方法?,F(xiàn)在,保留計數(shù)變?yōu)?。

現(xiàn)在,B類保留A類的對象和保留計數(shù)類A的對象變成2。

然后,C類對象的一個副本?,F(xiàn)在,它被創(chuàng)建為A類的實例變量的值相同的另一個實例。在這里,保留計數(shù)為1,而不是原來的對象的保留計數(shù)。這在圖中由虛線表示。

復制的對象將釋放C類使用釋放方法,并保留計數(shù)變?yōu)?,因此對象被銷毀。

在初始A類對象的情況下,保留計數(shù)為2,它有兩次被釋放,以便將其銷毀。這是通過類A和B類保留計數(shù)遞減為1和0,分別使用 release 語句。最后,對象將被破壞。

MRR基本規(guī)則

  • 我們擁有我們所創(chuàng)建的任何對象:我們創(chuàng)建了一個對象,使用方法的名字以 "alloc", "new", "copy" 或 "mutableCopy"開始

  • 我們可以把一個對象使用保留所有權(quán):接收到的對象通常是保證在收到它的方法仍然有效,并且該方法也可以安全地返回其調(diào)用對象。我們使用保留在兩種情況下:

    • 在執(zhí)行存取方法或者一個init方法,采取所有權(quán),我們要存儲一個對象的屬性值。

    • 為了防止一個對象被無效的一些其他的操作的一個副作用。

  • 當我們不再需要它,我們必須放棄所有權(quán)的對象,我們自己:我們放棄對象的所有權(quán),通過發(fā)送一個釋放消息或一個自動釋放的消息。在可可術(shù)語,放棄一個對象的所有權(quán),因此通常被稱為“釋放”一個對象。

  • 不能放棄擁有一個對象(不屬于自己):這只是推論明確說明以前的策略規(guī)則。

#import <Foundation/Foundation.h>

@interface SampleClass:NSObject
- (void)sampleMethod;
@end

@implementation SampleClass

- (void)sampleMethod
{
   NSLog(@"Hello, World! 
");
}

- (void)dealloc 
{
  NSLog(@"Object deallocated");
  [super dealloc];
}

@end

int main()
{
   /* my first program in Objective-C */
   SampleClass *sampleClass = [[SampleClass alloc]init];
   [sampleClass sampleMethod];
   NSLog(@"Retain Count after initial allocation: %d", 
   [sampleClass retainCount]);
   [sampleClass retain];
   NSLog(@"Retain Count after retain: %d", [sampleClass retainCount]);
   [sampleClass release];
   NSLog(@"Retain Count after release: %d", [sampleClass retainCount]);
   [sampleClass release];
   NSLog(@"SampleClass dealloc will be called before this");
   // Should set the object to nil
   sampleClass = nil;
   return 0;
}

當我們編譯上面的程序,我們會得到下面的輸出。

2013-09-28 04:39:52.310 demo[8385] Hello, World!
2013-09-28 04:39:52.311 demo[8385] Retain Count after initial allocation: 1
2013-09-28 04:39:52.311 demo[8385] Retain Count after retain: 2
2013-09-28 04:39:52.311 demo[8385] Retain Count after release: 1
2013-09-28 04:39:52.311 demo[8385] Object deallocated
2013-09-28 04:39:52.311 demo[8385] SampleClass dealloc will be called before this

“自動引用計數(shù)”或ARC

在自動引用計數(shù)或ARC時,系統(tǒng)使用相同的引用計數(shù)系統(tǒng)MRR,但它插入相應的內(nèi)存管理方法要求我們在編譯時間。我們強烈鼓勵使用ARC新的項目中。如果我們使用ARC,通常是有沒有需要了解本文檔中描述的底層實現(xiàn),盡管它可能在某些情況下是有益的。如需更多關(guān)于ARC,請參閱 過渡到ARC發(fā)布注釋.

正如上面所提到的,在ARC中我們需要不加釋放和保留的方法,因為這將得到編譯器的處理。事實上,底層的 Objective-C 程序仍然是一樣的。它使用的保留和釋放內(nèi)部的操作使它更容易為開發(fā)人員代碼不擔心這些操作的情況下,這將減少代碼編寫量和內(nèi)存泄漏的可能性。

還有另一個稱為垃圾收集的原則,這是用來在Mac OS-X以及MRR,但其在OS-XMountain Lion 中棄用以來,它已經(jīng)不隨著MRR討論。此外,iOS 的對象從未有過的垃圾收集特點。較ARC,在OS-X是沒有用垃圾收集。

下面是一個簡單的ARC例子

#import <Foundation/Foundation.h>

@interface SampleClass:NSObject
- (void)sampleMethod;
@end

@implementation SampleClass

- (void)sampleMethod
{
   NSLog(@"Hello, World! 
");
}

- (void)dealloc 
{
  NSLog(@"Object deallocated");
}

@end

int main()
{
   /* my first program in Objective-C */
   @autoreleasepool{
       SampleClass *sampleClass = [[SampleClass alloc]init];
       [sampleClass sampleMethod];
	   sampleClass = nil;
   }
   return 0;
}

當我們編譯上面的程序,我們會得到下面的輸出。

2013-09-28 04:45:47.310 demo[8385] Hello, World!
2013-09-28 04:45:47.311 demo[8385] Object deallocated