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

iOS應(yīng)用開(kāi)發(fā):什么是ARC?

移動(dòng)開(kāi)發(fā) iOS
ARC是iOS 5推出的新功能,全稱叫 ARC(Automatic Reference Counting)。簡(jiǎn)單地說(shuō),就是代碼中自動(dòng)加入了retain/release,原先需要手動(dòng)添加的用來(lái)處理內(nèi)存管理的引用計(jì)數(shù)的代碼可以自動(dòng)地由編譯器完成了。

ARC是什么

ARC基本規(guī)則

總結(jié)

 新年伊始,萬(wàn)象更新。新一年開(kāi)始,我們來(lái)更加深入了解一下iPhone開(kāi)發(fā)的內(nèi)部。作為開(kāi)始,我們先來(lái)了解一下ARC。

ARC是什么

ARC是iOS 5推出的新功能,全稱叫 ARC(Automatic Reference Counting)。簡(jiǎn)單地說(shuō),就是代碼中自動(dòng)加入了retain/release,原先需要手動(dòng)添加的用來(lái)處理內(nèi)存管理的引用計(jì)數(shù)的代碼可以自動(dòng)地由編譯器完成了。

該機(jī)能在 iOS 5/ Mac OS X 10.7 開(kāi)始導(dǎo)入,利用 Xcode4.2 可以使用該機(jī)能。簡(jiǎn)單地理解ARC,就是通過(guò)指定的語(yǔ)法,讓編譯器(LLVM 3.0)在編譯代碼時(shí),自動(dòng)生成實(shí)例的引用計(jì)數(shù)管理部分代碼。有一點(diǎn),ARC并不是GC,它只是一種代碼靜態(tài)分析(Static Analyzer)工具。

變化點(diǎn)

通過(guò)一小段代碼,我們看看使用ARC前后的變化點(diǎn)。

  1. @interface NonARCObject : NSObject {  
  2.     NSString *name;  
  3. }  
  4. -(id)initWithName:(NSString *)name;  
  5. @end  
  6.  
  7. @implementation NonARCObject  
  8. -(id)initWithName:(NSString *)newName {  
  9.     self = [super init];  
  10.     if (self) {  
  11.         name = [newName retain];  
  12.     }  
  13.     return self;  
  14. }  
  15.  
  16. -(void)dealloc {  
  17.     [name release];  
  18.     [Super dealloc];  
  19. }  
  20. @end  
  1. @interface ARCObject : NSObject {  
  2.     NSString *name;  
  3. }  
  4. -(id)initWithName:(NSString *)name;  
  5. @end  
  6.  
  7. @implementation ARCObject  
  8. -(id)initWithName:(NSString *)newName {  
  9.     self = [super init];  
  10.     if (self) {  
  11.         name = newName;  
  12.     }  
  13.     return self;  
  14. }  
  15. @end  
我們之前使用Objective-C中內(nèi)存管理規(guī)則時(shí),往往采用下面的準(zhǔn)則
  •    生成對(duì)象時(shí),使用autorelease
  •    對(duì)象代入時(shí),先autorelease后再retain
  •    對(duì)象在函數(shù)中返回時(shí),使用return [[object retain] autorelease];

而使用ARC后,我們可以不需要這樣做了,甚至連最基礎(chǔ)的release都不需要了。

使用ARC的好處

使用ARC有什么好處呢?

  •    看到上面的例子,大家就知道了,以后寫Objective-C的代碼變得簡(jiǎn)單多了,因?yàn)槲覀儾恍枰獡?dān)心煩人的內(nèi)存管理,擔(dān)心內(nèi)存泄露了
  •    代碼的總量變少了,看上去清爽了不少,也節(jié)省了勞動(dòng)力
  •    代碼高速化,由于使用編譯器管理引用計(jì)數(shù),減少了低效代碼的可能性

不好的地方

  •    記住一堆新的ARC規(guī)則 — 關(guān)鍵字及特性等需要一定的學(xué)習(xí)周期
  •    一些舊的代碼,第三方代碼使用的時(shí)候比較麻煩;修改代碼需要工數(shù),要么修改編譯開(kāi)關(guān)

關(guān)于第二點(diǎn),由于 XCode4.2 中缺省ARC就是 ON 的狀態(tài),所以編譯舊代碼的時(shí)候往往有"Automatic Reference Counting Issue"的錯(cuò)誤信息。

這個(gè)時(shí)候,可以將項(xiàng)目編譯設(shè)置中的“Objectice-C Auto Reference Counteting”設(shè)為NO。如下所示。

如果只想對(duì)某個(gè).m文件不適應(yīng)ARC,可以只針對(duì)該類文件加上 -fno-objc-arc 編譯FLAGS,如下圖。

ARC基本規(guī)則

  •     retain, release, autorelease, dealloc由編譯器自動(dòng)插入,不能在代碼中調(diào)用
  •     dealloc雖然可以被重載,但是不能調(diào)用[super dealloc]

由于ARC并不是GC,并需要一些規(guī)則讓編譯器支持代碼插入,所以必須清楚清楚了這些規(guī)則后,才能寫出健壯的代碼。

Objective-C對(duì)象

ObjectiveC中的對(duì)象,有強(qiáng)參照(Strong reference)和弱參照(Weak reference)之分,當(dāng)需要保持其他對(duì)象的時(shí)候,需要retain以確保對(duì)象引用計(jì)數(shù)加1。對(duì)象的持有者(owner)只要存在,那么該對(duì)象的強(qiáng)參照就一直存在。

對(duì)象處理的基本規(guī)則是
  •     只要對(duì)象的持有者存在(對(duì)象被強(qiáng)參照),那么就可以使用該對(duì)象
  •     對(duì)象失去了持有者后,即被破棄

強(qiáng)參照 (Strong reference)

(s1)

firstName作為”natsu”字符串對(duì)象的最初持有者,是該NSString類型對(duì)象的Strong reference。

(s2)

這里將firstName代入到aName中,即aName也成為了@”natsu”字符串對(duì)象的持有者,對(duì)于該對(duì)象,aName也是Strong reference。

(s3)

這里,改變firstName的內(nèi)容。生成新的字符串對(duì)象”maki”。這時(shí)候firstName成為”maki”的持有者,而@”natsu”的持有者只有aName。每個(gè)字符串對(duì)象都有各自的持有者,所以它們都在內(nèi)存中都存在。

(s4)

追加新的變量otherName, 它將成為@”maki”對(duì)象的另一個(gè)持有者。即NSString類型對(duì)象的Strong reference。

(s5)

將otherName代入到aName,這時(shí),aName將成為@”maki”字符串對(duì)象的持有者。而對(duì)象@”natsu”已經(jīng)沒(méi)有持有者了,該對(duì)象將被破棄。

弱參照 (Weak reference)

接下來(lái)我們來(lái)看看弱參照 (Weak reference) 的使用方式。

(w1)

與強(qiáng)參照方式同樣,firstName作為字符串對(duì)象@”natsu”的持有者存在。即是該NSString類型對(duì)象的Strong reference。

(w2)

使用關(guān)鍵字__weak,聲明弱參照weakName變量,將firstName代入。這時(shí)weakName雖然參照@”natsu”,但仍是Weak reference。即weakName雖然能看到@”natsu”,但不是其持有者。

(w3)

firstName指向了新的對(duì)象@”maki”,成為其持有者,而對(duì)象@”natsu”因?yàn)闆](méi)有了持有者,即被破棄。同時(shí)weakName變量將被自動(dòng)代入nil。

引用關(guān)鍵字

ARC中關(guān)于對(duì)象的引用參照,主要有下面幾關(guān)鍵字。使用strong, weak, autoreleasing限定的變量會(huì)被隱式初始化為nil。

  • __strong

變量聲明缺省都帶有__strong關(guān)鍵字,如果變量什么關(guān)鍵字都不寫,那么缺省就是強(qiáng)參照。

  • __weak

上面已經(jīng)看到了,這是弱參照的關(guān)鍵字。該概念是新特性,從 iOS 5/ Mac OS X 10.7 開(kāi)始導(dǎo)入。由于該類型不影響對(duì)象的生命周期,所以如果對(duì)象之前就沒(méi)有持有者,那么會(huì)出現(xiàn)剛創(chuàng)建就被破棄的問(wèn)題,比如下面的代碼。

  1. NSString __weak *string = [[NSString alloc] initWithFormat:@"First Name: %@", [self firstName]];  
  2. NSLog(@"string: %@", string); //此時(shí) string為空  

如果編譯設(shè)定OS版本 Deployment Target 設(shè)定為這比這低的版本,那么編譯時(shí)將報(bào)錯(cuò)(The current deployment target does not support automated __weak references),這個(gè)時(shí)候,我們可以使用下面的__unsafe_unretained。

弱參照還有一個(gè)特征,即當(dāng)參數(shù)對(duì)象失去所有者之后,變量會(huì)被自動(dòng)付上nil (Zeroing)。

  • __unsafe_unretained

該關(guān)鍵字與__weak一樣,也是弱參照,與__weak的區(qū)別只是是否執(zhí)行nil賦值(Zeroing)。但是這樣,需要注意變量所指的對(duì)象已經(jīng)被破棄了,地址還還存在,但內(nèi)存中對(duì)象已經(jīng)沒(méi)有了。如果還是訪問(wèn)該對(duì)象,將引起「BAD_ACCESS」錯(cuò)誤。

  • __autoreleasing

該關(guān)鍵字使對(duì)像延遲釋放。比如你想傳一個(gè)未初始化的對(duì)像引用到一個(gè)方法當(dāng)中,在此方法中實(shí)例化此對(duì)像,那么這種情況可以使用__autoreleasing。他被經(jīng)常用于函數(shù)有值參數(shù)返回時(shí)的處理,比如下面的例子。

  1. - (void) generateErrorInVariable:(__autoreleasing NSError **)paramError {  
  2.     ....  
  3.     *paramError = [[NSError alloc] initWithDomain:@"MyApp" code:1 userInfo:errorDictionary];  
  4. }  
  5.  
  6. ....  
  7. {  
  8.     NSError *error = nil;  
  9.     [self generateErrorInVariable:&error];  
  10.     NSLog(@"Error = %@", error);  
  11. }  

又如函數(shù)的返回值是在函數(shù)中申請(qǐng)的,那么希望釋放是在調(diào)用端時(shí),往往有下面的代碼。

  1. -(NSString *)stringTest  
  2. {  
  3.     NSString *retStr = [NSString stringWithString:@"test"];  
  4.  
  5.     return [[retStr retain] autorelease];  
  6. }  
  7.  
  8. // 使用ARC  
  9.  
  10. -(NSString *)stringTest  
  11. {  
  12.     __autoreleasing NSString *retStr = [NSString alloc] initWithString:@"test"];  
  13.  
  14.     return retStr;  
  15. }  

即當(dāng)方法的參數(shù)是id*,且希望方法返回時(shí)對(duì)象被autoreleased,那么使用該關(guān)鍵字。

總結(jié)

今天,我們看到了基本的ARC使用規(guī)則
  •     代碼中不能使用retain, release, retain, autorelease
  •     不重載dealloc(如果是釋放對(duì)象內(nèi)存以外的處理,是可以重載該函數(shù)的,但是不能調(diào)用[super dealloc])
  •     不能使用NSAllocateObject, NSDeallocateObject
  •     不能在C結(jié)構(gòu)體中使用對(duì)象指針
  •     id與void *間的如果cast時(shí)需要用特定的方法(__bridge關(guān)鍵字)
  •     不能使用NSAutoReleasePool、而需要@autoreleasepool塊
  •     不能使用“new”開(kāi)始的屬性名稱 (如果使用會(huì)有下面的編譯錯(cuò)誤”Property’s synthesized getter follows Cocoa naming convention for returning ‘owned’ objects”)

 原文地址:http://www.yifeiyang.net/development-of-the-iphone-simply-1/

責(zé)任編輯:佚名 來(lái)源: 易飛揚(yáng)博客
相關(guān)推薦

2012-01-18 13:46:37

ARCiOS

2013-04-16 15:49:31

iOS開(kāi)發(fā)是否用ARC

2015-03-30 14:34:08

混合云應(yīng)用開(kāi)發(fā)混合云部署

2014-11-19 10:08:47

2011-05-11 10:02:37

iOS

2013-09-13 13:16:05

2011-07-08 14:58:16

iPhone Xcode iOS

2011-08-11 16:50:04

iOSTwitter

2011-07-26 11:08:23

iOS 錄像 錄音

2011-08-08 13:26:48

iOS開(kāi)發(fā) Twitter

2011-08-17 14:20:21

IOS開(kāi)發(fā)GraphicsCon

2012-02-13 13:45:04

MonoTouch.NETiOS應(yīng)用

2011-08-17 14:30:34

iOS開(kāi)發(fā)窗口

2012-02-02 10:14:14

2014-06-13 11:06:36

RoboVMiOS應(yīng)用

2014-03-17 15:16:02

移動(dòng)開(kāi)發(fā)iOS應(yīng)用

2013-01-11 15:06:13

iOS開(kāi)發(fā)移動(dòng)應(yīng)用iPhone

2012-05-11 09:50:49

iOSAndroid移動(dòng)應(yīng)用

2017-03-13 11:04:24

后端開(kāi)發(fā)

2016-12-14 13:51:56

點(diǎn)贊
收藏

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