iOS開發之__bridge,__bridge_transfer和__bridge_retained

來源:互聯網
上載者:User

標籤:format   encoding   tty   bridged   nsstring   cto   com   select   項目   

 

本文轉至:http://www.qingpingshan.com/rjbc/ios/157477.html

引言

Core Foundation架構 (CoreFoundation.framework) 是一組C語言介面,它們為iOS應用程式提供基本資料管理和服務功能。下面列舉該架構支援進行管理的資料以及可提供的服務:

1.群體資料類型 (數組、集合等)

2.程式包

3.字串管理

4.日期和時間管理

5.未經處理資料塊管理

6.偏好管理

7.URL及資料流操作

8.線程和RunLoop

9.連接埠和soket通訊

Core Foundation架構和Foundation架構緊密相關,它們為相同功能提供介面,但Foundation架構提供Objective-C介面。如果您將Foundation對象和Core Foundation類型摻雜使用,則可利用兩個架構之間的 “toll-free bridging”。所謂的Toll-free bridging是說您可以在某個架構的方法或函數同時使用Core Foundatio和Foundation 架構中的某些類型。很多資料類型支援這一特性,其中包括群體和字串資料型別。每個架構的類和類型描述都會對某個對象是否為 toll-free bridged,應和什麼對象橋接進行說明。

Toll-free bridging 是ARC下OC對象和Core Foundation對象之間的橋樑

在開發iOS應用程式時我們有時會用到Core Foundation對象,下面簡稱CF。例如Core Graphics、Core Text,並且我們可能需要將CF對象和OC對象進行相互轉化,我們知道,ARC環境下,編譯器不會自動管理CF對象的記憶體,我們需要手動管理。這就是我們在建立一個CF對象以後需要我們使用CFRelease將其手動釋放。

那麼CF和OC相互轉化的時候該如何管理記憶體呢?

我們可以通過 bridge, bridge_transfer,__bridge_retained 來進行記憶體管理

1.__bridge

CF和OC對象轉化時只涉及物件類型不涉及對象所有權的轉化

//Image I/O 從 NSBundle 讀取圖片資料   NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"image" ofType:@"png"];    CGImageSourceRef source = CGImageSourceCreateWithURL((__bridge CFURLRef)[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"image" ofType:@"png"]], NULL);

如果上面不添加 bridge ,在ARC環境下,系統會給出錯誤提示和錯誤修正,點擊錯誤提示的話,系統會為我們自動添加 bridge ,因為在OC與CF的轉化時只涉及到物件類型沒有涉及到對象所有權的轉化,所以上述代碼不需要對CF的對象進行釋放,即不需要添加CFRelease

注釋: iOS ARC 和 非ARC 之間的轉換方法  1,選擇項目中的Targets,選中你所要操作的Target,  2,選Build Phases,在其中Complie Sources中選擇需要ARC的檔案雙擊,       並在輸入框中輸入:-fobjc-arc,如果不要ARC則輸入:-fno-objc-arc

為瞭解決這一問題,我們使用 __bridge 關鍵字來實現id類型與void*類型的相互轉換。

id obj = [[NSObject alloc] init];    void *p = (__bridge void *)(obj);    NSLog(@"obj retainCount %ld",[(id)p retainCount]);

輸出結果:

CFDemo[2932:777997] obj retainCount 1

2.__bridge_transfer

常用在CF對象轉化成OC對象時,將CF對象的所有權交給OC對象,此時ARC就能自動管理該記憶體,作用同CFBridgingRelease()

如果非ARC的時候,我們可能需要寫下面的代碼。

// p 變數原先持有對象的所有權id obj = (id)p;[obj retain];[(id)p release];

那麼ARC有效後,我們可以用下面的代碼來替換:

// p 變數原先持有對象的所有權id obj = (__bridge_transfer id)p;

可以看出來, bridge_retained 是編譯器替我們做了 retain 操作,而 bridge_transfer 是替我們做了 release。

3. 

bridge_retained

bridge_transfer 相反,常用在將OC對象轉化成CF對象,且OC對象的所有權也交給CF對象來管理,即OC對象轉化成CF對象時,涉及到物件類型和對象所有權的轉化,作用同CFBridgingRetain()

先來看使用 __bridge_retained 關鍵字的例子程式:

id obj = [[NSObject alloc] init];void *p = (__bridge_retained void *)obj;

此時retainCount 會被加1;

從名字上我們應該能理解其意義:類型被轉換時,其對象的所有權也將被變換後變數所持有。如果不是ARC代碼,類似下面的實現:

id obj = [[NSObject alloc] init];void *p = obj;[(id)p retain];

ARC如何擷取retainCount

NSLog(@"Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)myObject));

來來來舉個例子:

NSString *string = [NSString stringWithFormat:@""];    CFStringRef cfString = (__bridge CFStringRef)string;    CFStringRef cfStr = (__bridge_retained CFStringRef)string;    CFRelease(cfString);// 由於Core Foundation的對象不屬於ARC的管理範疇,所以需要自己release    CFRelease(cfStr);

使用 __bridge_retained 可以通過轉換目標處(cfStr)的 retain 處理,來使所有權轉移。即使 string 變數被釋放,cfString變數也變釋放,cfStr 還是可以使用具體的對象。只是有一點,由於Core Foundation的對象不屬於ARC的管理範疇,所以需要自己release。

CFStringRef cfString= CFURLCreateStringByAddingPercentEscapes( NULL, (__bridge CFStringRef)text, NULL, CFSTR("!*’();:@&=+$,/?%#[]"), CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));    NSString *ocString = (__bridge_transfer CFStringRef)cfString;

所有權被轉移的同時,被轉換變數將失去對象的所有權。當Core Foundation物件類型向Objective-C物件類型轉換的時候,會經常用到 __bridge_transfer 關鍵字。

總結:

  1. Core Foundation 物件類型不在 ARC 管理範疇內
  2. Cocoa Framework::Foundation 物件類型(即一般使用到的Objectie-C物件類型)在 ARC 的管理範疇內 
    3. bridge, bridge_transfer和__bridge_retained 是CF和OC的橋樑
  3. 如果不在 ARC 管理範疇內的對象,那麼要清楚 release 的責任應該是誰以及各種對象的生命週期是怎麼樣的

這是目前在學習ImageIO蘋果官方提供的圖片解碼器,遇到OC和CF之間相互轉化的一些問題,重新整理,細緻的瞭解下,以方便後期更加深入的學習。

iOS開發之__bridge,__bridge_transfer和__bridge_retained

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.