自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

剖析Objective-C內(nèi)存管理規(guī)則

移動開發(fā) iOS
本文介紹的是詳解Objective-C 2.0 關(guān)于Obj-C內(nèi)存管理規(guī)則,主要介紹了內(nèi)存機(jī)制,我們來看詳細(xì)內(nèi)容。

詳解Objective-C 2.0 關(guān)于Objective-C內(nèi)存管理規(guī)則是本文要介紹的內(nèi)容,不多說,先來看內(nèi)容。Objective-C 2.0增加了一些新的東西,包括屬性和垃圾回收。那么,我們在學(xué)習(xí)Objective-C 2.0之前,最好應(yīng)該先了解,從前是什么樣的,為什么Objective-C 2.0要增加這些支持。

這一切都跟Cocoa內(nèi)存的管理規(guī)則有關(guān)系,我們知道,Objective-C中所有變量都定義為指針。指針是一個特殊的變量,它里面存儲的數(shù)值被解釋成為內(nèi)存里的一個地址,如果使用不當(dāng),就會出錯或者造成內(nèi)存的泄露。要了解這些,就需要看看其內(nèi)存管理的規(guī)則到底是什么樣的。

這篇文章也應(yīng)該做為蘋果開發(fā)工具中提供的性能調(diào)試工具Instruments使用前必讀知識進(jìn)行閱讀。要知道,如果你使用Objective-C 2.0,那么本文描述的大部分工作你都不需要自己去處理了。但是這并不意味著你可以不了解它,相反,只有你對內(nèi)存管理規(guī)則更加了解,你才能更好地使用Objective-C 2.0帶來的便利。

當(dāng)Cocoa新手在進(jìn)行內(nèi)存管理時,他們看上去總是把事情變得更為復(fù)雜。遵循幾個簡單的規(guī)則就可以把生活變得更簡單。而不遵循這些規(guī)則,他們幾乎一定會造成諸如內(nèi)存泄露或者將消息發(fā)送給釋放掉的對象而出現(xiàn)的的運(yùn)行錯誤。

Cocoa不使用垃圾回收(當(dāng)然,Objective-C 2.0之后開始就使用了),你必須通過計算reference的數(shù)量進(jìn)行自己的內(nèi)存管理,使用-retain, -release和-autorelease。

方法描述

retain

將一個對象的reference數(shù)量增加1。

release

將一個對象的reference數(shù)量減少1。

autorelease

在未來某些時候?qū)eference數(shù)量減少1.

alloc

為一個對象分配內(nèi)存,并設(shè)置保留值數(shù)量(retain count)為1。

copy

復(fù)制一個對象,并將其做為返回值。同時設(shè)置保留值數(shù)量(retain count)為1。

保留值數(shù)量規(guī)則
1、在一定的代碼段中,使用-copy,-alloc和-retain的次數(shù)應(yīng)該和-release,-autorelease保持一致。

2、使用便利構(gòu)造方法創(chuàng)建的對象(比如NSString的stringWithString)可以被認(rèn)為會被自動釋放。(autoreleased)

3、在使用你自己的參數(shù)實(shí)例時,需要實(shí)現(xiàn)-dealloc方法來釋放。

例子

  1. -alloc / -release  
  2.  
  3. - (void)printHello   
  4. {  
  5.  NSString *string;  
  6.  string = [[NSString alloc] initWithString:@"Hello"];  
  7.  NSLog(string);  
  8.  // 我們用 alloc 創(chuàng)建了NSString,那么需要釋放它  
  9.  [string release];  

便利構(gòu)造方法

  1. (void)printHello   
  2.  
  3. NSString *string;  
  4. string = [NSString stringWithFormat:@"Hello"];  
  5. NSLog(string);  
  6. // 我們用便利構(gòu)造方法創(chuàng)建的NSString  
  7. //我們可以認(rèn)為它會被自動釋放  

永遠(yuǎn)使用存取方法

雖然有時候你可能會認(rèn)為這很麻煩,但是如果你始終使用了存取方法,造成內(nèi)存管理問題的麻煩將會降低很多。

如果你在代碼實(shí)例的參數(shù)中頻繁使用-retain和-release,幾乎可以肯定你做了錯誤的事情。

例子

假設(shè)我們希望設(shè)置一個Counter對象的數(shù)量值。

  1. @interface Counter : NSObject  
  2. {  
  3.  NSNumber *count;  

為了獲取和設(shè)置count值,我們定義兩個存取方法:

  1. - (NSNumber *)count   
  2. {  
  3.  return count;  
  4.  // 無需retain或者release,  
  5.  // 僅僅傳遞數(shù)值  
  6. }  
  7. - (void)setCount:(NSNumber *)newCount   
  8. {  
  9.  // newCount值會被自動釋放,那么我們希望保留這個newCount  
  10.  // 所以需要在這里retain。  
  11.  [newCount retain];  
  12.  // 由于我們在這個方法中僅僅改變了計算數(shù)量的對象,我們可以在這里先釋放它。因?yàn)閇nil release]在objective-c中也是允許的,所以即使count值沒有被指定,也可以這樣調(diào)用。  
  13.  //我們必須在[newCount retain]之后再釋放count,因?yàn)橛锌赡苓@兩個對象的指針是同一個。我們不希望不小心釋放它。  
  14.  [count release];  
  15.  // 重新指定  
  16.  count = newCount;  

命名約定,注意存取方法的命名約定遵循一個模式: -參數(shù)名 和 -set參數(shù)名。

遵循這一約定,會使你的代碼可讀性更強(qiáng),而且,更重要地是你可以在后面使用key-value編碼。(參閱NSKeyValueCoding協(xié)議)。

由于我們有一個對象實(shí)例參數(shù),我們必須實(shí)現(xiàn)一個釋放方法:

  1. (void)dealloc   
  2. {  
  3.  [self setCount:nil];  
  4.  [super dealloc];  

假設(shè)我們希望實(shí)現(xiàn)一個方法重置計數(shù)器,我們會有很多選擇。在最開始,我們使用了一個 便利構(gòu)造方法,所以我們假設(shè)新的數(shù)值是自動釋放的。我們不需要發(fā)送任何retain或者release消息。

  1. (void)reset   
  2. {  
  3.  NSNumber *zero = [NSNumber numberWithInt:0];  
  4.  [self setCount:zero];  

然而,如果我們使用-alloc方法建立的NSNumber實(shí)例,那我們必須同時使用一個-release。

  1. (void)reset   
  2.  
  3. NSNumber *zero = [[NSNumber alloc] initWithInt:0];  
  4. [self setCount:zero];  
  5. [zero release];  

常見錯誤

在簡單的情況下,以下代碼幾乎一定可以正常運(yùn)行,但是由于可能沒有使用存取方法,下面的代碼在某些情況下幾乎一定會出問題。

錯誤-沒有使用存取方法

  1. (void)reset   
  2. {  
  3.  NSNumber *zero = [[NSNumber alloc] initWithInt:0];  
  4.  [count release]  
  5.  count = zero;  

錯誤-實(shí)例泄露

  1.  (void)reset   
  2. {  
  3.  NSNumber *zero = [[NSNumber alloc] initWithInt:0];  
  4.  [self setCount:zero];  

新建的NSNumber數(shù)值數(shù)量是1(通過alloc),而我們在這個方法里沒有發(fā)出-release消息。那么這個NSNumber就永遠(yuǎn)不會被釋放了,這樣就會造成內(nèi)存泄露。

錯誤-對已經(jīng)釋放的實(shí)例發(fā)送-release消息

  1. - (void)reset   
  2. {  
  3.  NSNumber *zero = [NSNumber numberWithInt:0];  
  4.  [self setCount:zero];  
  5.  [zero release];  

你隨后在存取count的時候在這里就會出錯。這個簡便構(gòu)造方法會返回一個自動釋放的對象,你無需發(fā)送其他釋放消息。

這樣寫代碼意味著,由于對象已經(jīng)被自動釋放,那么當(dāng)你釋放時,retain count將被減至0,對象已經(jīng)不存在了。當(dāng)你下次希望獲取count值時,你的消息會發(fā)到一個不存在的對象(通常這樣你會得到一個SIGBUS 10的錯誤提示)。

經(jīng)常造成混淆的情況

數(shù)組和其他集合類

當(dāng)對象被加入到數(shù)組、字典或者集合中,集合類會將其保留。當(dāng)集合被釋放的同時,對象也會收到一個釋放消息。如果你希望寫一個建立數(shù)字?jǐn)?shù)組的例子,你可能會這么寫:

  1. NSMutableArray *array;  
  2. int i;  
  3. // …  
  4. for (i = 0; i < 10; i++)   
  5. {  
  6.  NSNumber *n = [NSNumber numberWithInt: i];  
  7.  [array addObject: n];  

在這個例子里,你無需保留新建的數(shù)值,因?yàn)閿?shù)組會幫你保留。

  1. NSMutableArray *array;  
  2. int i;  
  3. // …  
  4. for (i = 0; i < 10; i++)   
  5. {  
  6.  NSNumber *n = [[NSNumber alloc] initWithInt: i];  
  7.  [array addObject: n];  
  8.  [n release];  

本例中,在for循環(huán)里你需要給n發(fā)送一個-release消息,因?yàn)槟阈枰冀K在-alloc之后將n的數(shù)量保持為1。這么做的原因是當(dāng)其通過-addObject:方法被添加至數(shù)組中時,數(shù)組已經(jīng)將其保存起來。即使你釋放了n,但是這個數(shù)字由于已經(jīng)保存在數(shù)組里,所以不會被釋放。

為了了解這些,假設(shè)你自己就是編寫數(shù)組類的人。你不希望接收的對象未經(jīng)你同意就消失,所以你會在對象傳遞進(jìn)來時,對其發(fā)送一個-retain消息。如果他們被刪除,你同時也要對應(yīng)地發(fā)送一個-release消息。在你自己-dealloc時,你也要給你收到的所有對象發(fā)送一個-release。

小結(jié):詳解Objective-C 2.0 關(guān)于Objective-C內(nèi)存管理規(guī)則的內(nèi)容介紹完了,希望本文對你有所幫助。

責(zé)任編輯:zhaolei 來源: Cocoa China
相關(guān)推薦

2011-07-19 15:15:09

Objective-C 內(nèi)存

2011-07-21 09:42:27

Objective-C 內(nèi)存 Autoreleas

2013-04-11 14:37:36

Objective-CiOS內(nèi)存管理系統(tǒng)自動創(chuàng)建新的aut

2013-04-11 14:32:00

Objective-CiOS開發(fā)內(nèi)存管理@synthesize

2011-05-11 15:45:50

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

2011-07-20 17:04:43

Objective-C 內(nèi)存 內(nèi)存泄露

2011-07-21 10:10:42

Objective-C 內(nèi)存 Autoreleas

2011-07-21 09:32:07

Objective-C 內(nèi)存 Autoreleas

2011-08-01 11:37:41

iPhone Objective- 內(nèi)存

2011-08-16 17:43:47

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

2013-04-11 14:16:57

Objective-CiOS開發(fā)內(nèi)存管理

2011-07-29 16:08:31

Objective-C 內(nèi)存

2011-08-18 13:28:35

Objective-C內(nèi)存

2011-07-27 17:10:30

Objective-C 持久化

2013-04-11 13:57:27

Objective-CiOS開發(fā)內(nèi)存管理

2015-07-08 10:51:27

Objective-CRuntime

2011-07-22 15:42:39

Objective-C UIView 內(nèi)存

2011-08-10 18:07:29

Objective-C反射

2011-05-11 15:58:34

Objective-C

2013-03-27 12:54:00

iOS開發(fā)Objective-C
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號