日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Foundation和Core Foundation掺杂使用桥接 Toll-Free Bridging

發布時間:2023/12/15 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Foundation和Core Foundation掺杂使用桥接 Toll-Free Bridging 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在cocoa application的應用中,我們有時會使用Core Foundation(CF),我們經常會在Objective-C和CF之間進行轉化。系統使用arc的狀態下,編譯器不能自動管理CF的內存,這時候你必須使用CFRetain和CFRelease來進行CF的內存的管理。 具體的CF內存管理規則見: Memory Management Programming Guide for Core Foundation 在OC和FC之間進行轉化的時候,主要是對象的歸屬問題。共有兩種方式: 1、使用宏,可以標識歸屬者從OC到CF,還是從CF到OC。 NS_INLINE CFTypeRef CFBridgingRetain(id X) {? return (__bridge_retain CFTypeRef)X;? }? NS_INLINE id CFBridgingRelease(CFTypeRef X) {? return (__bridge_transfer id)X;? } 2、使用轉化符,如:__bridge,__bridge_transfer,__bridge_retained id my_id;? CFStringRef my_cfref;? …? NSString ? *a = (__bridge NSString*)my_cfref; ? ? // Noop cast.? CFStringRef b = (__bridge CFStringRef)my_id; ? ? ?// Noop cast.? …? NSString ? *c = (__bridge_transfer NSString*)my_cfref; // -1 on the CFRef? CFStringRef d = (__bridge_retained CFStringRef)my_id; ?// returned CFRef is +1 下面以詳細的例子來介紹一下OC和CF在arc下內存管理的詳細寫法.下面以CFURLCreateStringByAddingPercentEscapes()函數為例說一下在ARC下的寫法和非ARC下的寫法。 非ARC模式下的寫法: #pragma mark – View lifecycle? - (void)viewDidLoad? {? [super viewDidLoad];? NSLog(@"=%@", [self escape:@"wangjun"]);? }? -(NSString *)escape:(NSString *)text? {? return (NSString *)CFURLCreateStringByAddingPercentEscapes(? NULL,? (__bridge CFStringRef)text,? NULL,? CFSTR("!*’();:@&=+$,/?%#[]"), CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));;? } 使用instruments檢測,沒有內存泄漏。 下面把上面工程改為arc模式。 可以看到xcode自動把上面函數轉化為: #pragma mark – View lifecycle? - (void)viewDidLoad? {? [super viewDidLoad];? NSLog(@"=%@", [self escape:@"wangjun"]);? }? -(NSString *)escape:(NSString *)text? {? return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(? NULL,? (__bridge CFStringRef)text,? NULL,? CFSTR("!*’();:@&=+$,/?%#[]"), CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));;? } 在arc中,CF和OC之間的轉化橋梁是 __bridge,有兩種方式: __bridge_transfer ?ARC接管管理內存 __bridge_retained ?ARC釋放內存管理 上面的方法是從CF轉化為OC NSString對象,使用的__bridge_transfer ,對象所有者發生轉變,由CF到OC,最后由ARC接管內存管理。運行上面的代碼,用instruments檢測,是沒有內存泄漏的。 上面代碼等同于: - (NSString *)escape:(NSString *)text? {? return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(? NULL,? (__bridge CFStringRef)text,? NULL,? CFSTR("!*’();:@&=+$,/?%#[]"), CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding)));} 如果將上述代碼改為: -(NSString *)escape:(NSString *)text? {? return (__bridge NSString *)CFURLCreateStringByAddingPercentEscapes(? NULL,? (__bridge CFStringRef)text,? NULL,? CFSTR("!*’();:@&=+$,/?%#[]"), CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));;? } 編譯也會成功,但是這時候用instruments檢測,可以發現內存泄漏: 由于CF轉化完OC,沒有自己釋放內存,同時也沒有把內存管理交給ARC,所以出現內存泄漏。由于__bridge只是同一個對象的引用,內存的所有權沒有發生變化。 下面在說一下oc到CF的轉化,需要把OC的內存管理權釋放掉。 NSString *s1 = [[NSString alloc] initWithFormat:@"Hello, %@!", name];? CFStringRef s2 = (__bridge_retained CFStringRef)s1;? // do something with s2 // . . .? CFRelease(s2); 最后由CF進行內存釋放。 上面代碼等同于: CFStringRef s2 = CFBridgingRetain(s1);? // . . .? CFRelease(s2); 下面總結一下我們使用ARC情況下。oc和CF互相轉化的原則: CF轉化為OC時,并且對象的所有者發生改變,則使用CFBridgingRelease()或__bridge_transfer 。 OC轉化為CF時,并且對象的所有者發生改變,則使用CFBridgingRetain()或__bridge_retained 當一個類型轉化到另一種類型時,但是對象所有者沒有發生改變,則使用__bridge. 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的Foundation和Core Foundation掺杂使用桥接 Toll-Free Bridging的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。