久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

什么是 ARC

 quasiceo 2015-03-04

什么是 ARC

發(fā)表于3年前(2012-07-24 15:10)   閱讀(242) | 評論(1 2人收藏此文章, 我要收藏
0

3月21日 深圳 OSC 源創(chuàng)會正在報名中,,送華為海思開發(fā)板

ARC


ARC是什么

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

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

變化點

通過一小段代碼,我們看看使用ARC前后的變化點,。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@interface  NonARCObject : NSObject {
    NSString *name;
}
-(id)initWithName:(NSString *)name;@end  @implementation NonARCObject -(id)initWithName:(NSString *)newName {
    self = [super init];
    if (self) {
        name = [newName retain];
    }
    return self;
}

-(void)dealloc {
    [name release];
    [Super dealloc];
}@end  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@interface  ARCObject : NSObject {
    NSString *name;
}
-(id)initWithName:(NSString *)name;@end  @implementation ARCObject -(id)initWithName:(NSString *)newName {
    self = [super init];
    if (self) {
        name = newName;
    }
    return self;
}@end  
我們之前使用Objective-C中內(nèi)存管理規(guī)則時,,往往采用下面的準則

  • 生成對象時,使用autorelease
  • 對象代入時,,先autorelease后再retain
  • 對象在函數(shù)中返回時,,使用return [[object retain] autorelease];

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

使用ARC的好處

使用ARC有什么好處呢?

  • 看到上面的例子,,大家就知道了,,以后寫Objective-C的代碼變得簡單多了,因為我們不需要擔心煩人的內(nèi)存管理,,擔心內(nèi)存泄露了
  • 代碼的總量變少了,,看上去清爽了不少,也節(jié)省了勞動力
  • 代碼高速化,,由于使用編譯器管理引用計數(shù),,減少了低效代碼的可能性

不好的地方

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

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

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

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

ARC基本規(guī)則

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

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

Objective-C對象

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

對象處理的基本規(guī)則是

  • 只要對象的持有者存在(對象被強參照),,那么就可以使用該對象
  • 對象失去了持有者后,即被破棄
強參照 (Strong reference)
(s1)

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

(s2)

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

(s3)

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

(s4)

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

(s5)

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

弱參照 (Weak reference)

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

(w1)

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

(w2)

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

(w3)

firstName指向了新的對象@”maki”,,成為其持有者,而對象@”natsu”因為沒有了持有者,,即被破棄,。同時weakName變量將被自動代入nil。

引用關(guān)鍵字

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

__strong

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

__weak

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

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

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

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

__unsafe_unretained

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

__autoreleasing

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

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

....
{
    NSError *error = nil;
    [self generateErrorInVariable:&error];
    NSLog(@"Error = %@", error);
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-(NSString *)stringTest {
    NSString *retStr = [NSString stringWithString:@"test"];

    return [[retStr retain] autorelease];
}// 使用ARC -(NSString *)stringTest {
    __autoreleasing NSString *retStr = [NSString alloc] initWithString:@"test"];

    return retStr;
}

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

總結(jié)

今天,我們看到了基本的ARC使用規(guī)則

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

今后,,我們將更加深入ARC,,學習其更多的特性。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導購買等信息,謹防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多