[iOS] Core Foundation - Toll-Free Bridged Types

這篇文檔是比較基礎(chǔ)的,翻譯下來備用。原文地址

介紹

Core Foundation框架和Foundation框架有一些數(shù)據(jù)類型可以交換替代使用。如果數(shù)據(jù)類型可以相互替代,那么這種數(shù)據(jù)類型也被稱為對象橋接類型。這意味著你可以用相同的數(shù)據(jù)結(jié)構(gòu)(對象橋接類型可能本質(zhì)上是由于數(shù)據(jù)結(jié)構(gòu)相同?)作為Core Foundation函數(shù)的調(diào)用參數(shù)或者作為Foundation方法的接收者。例如,NSLocale對象對應(yīng)的是Core Foundation中的CFLocale對象。
不是所有對象都是可以對象橋接的,即使他們的名字暗示他們是對象橋接類型。例如,NSRunLoopCFRunLoop不能橋接,NSBundleCFBundle不能橋接,NSDateFormatterCFDateFormatter不能橋接。文章底部的表格提供了支持對象橋接的數(shù)據(jù)類型。

注意:如果你為Core Foundation集合對象寫了一個在使用它時執(zhí)行的自定義回調(diào), 包括空的回調(diào), 在使用Objective-C訪問這個Core Foundation集合對象時它的內(nèi)存管理行為是不明確的。

聲明和對象生命周期的含義

通過對象橋接,例如在方法中你看到NSLocale *參數(shù),可以傳遞CFLocaleRef,在函數(shù)中看到CFLocaleRef參數(shù),可以傳遞NSLocale *實例。你必須要為編譯器提供其他信息:首先,你必須把一種類型聲明為對應(yīng)的橋接類型;另外,你必須指明對象的生命周期。
編譯器理解Objective-C方法返回的Core Foundation類型并且遵守Cocoa命名習(xí)俗。例如,編譯器知道在iOS中,通過調(diào)用UIColorCGColor方法返回的CGColor對象并不被認(rèn)可,你仍然必須為其聲明合適的類型,下面代碼塊為例:

NSMutableArray *colors = [NSMutableArray arrayWithObject:(id)[[UIColor darkGrayColor] CGColor]]; // 不聲明為id類型會報出"Incompatible pointer types sending 'CGColorRef _Nonnull' (aka 'struct CGColor *') to parameter of type 'id _Nonnull' "這個警告
[colors addObject:(id)[[UIColor lightGrayColor] CGColor]];

編譯器不自動管理Core Foundation對象的生命周期。你需要告訴編譯器對象的所有權(quán)(請參考我之前翻譯的文檔 [iOS]CoreFoundation - Ownership Policy ),通過聲明或者使用Core Foundation類型的宏:

  • __bridgeObjective-CCore Foundation之間傳遞了一個指針,但是沒有傳遞對象的所有權(quán)。
  • __bridge_retained或者CFBridgingRetain將一個Objective-C指針轉(zhuǎn)換為Core Foundation指針,并且將Objective-C對象的所有權(quán)交給你(如果要釋放對象需要調(diào)用Release函數(shù))。
  • __bridge_transfer或者CFBridgingRelease非Objective-C指針移動到Objective-C并且將對象的所有權(quán)交給ARC,所以ARC有責(zé)任在不使用該對象的時候?qū)⑵溽尫拧?br> 上述中部分內(nèi)容體現(xiàn)在下面的例子中:
NSLocale *gbNSLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_GB"];
CFLocaleRef gbCFLocale = (__bridge CFLocaleRef)gbNSLocale;
CFStringRef cfIdentifier = CFLocaleGetIdentifier(gbCFLocale);
NSLog(@"cfIdentifier: %@", (__bridge NSString *)cfIdentifier);
// Logs: "cfIdentifier: en_GB"
 
CFLocaleRef myCFLocale = CFLocaleCopyCurrent();
NSLocale *myNSLocale = (NSLocale *)CFBridgingRelease(myCFLocale);
NSString *nsIdentifier = [myNSLocale localeIdentifier];
CFShow((CFStringRef)[@"nsIdentifier: " stringByAppendingString:nsIdentifier]);
// Logs identifier for current locale

接下來的例子顯示了遵守 Core Foundation內(nèi)存管理規(guī)則Core Foundation內(nèi)存管理函數(shù) 的使用:

- (void)drawRect:(CGRect)rect {
    
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
    CGFloat locations[2] = {0.0, 1.0};
    NSMutableArray *colors = [NSMutableArray arrayWithObject:(id)[[UIColor darkGrayColor] CGColor]];
    [colors addObject:(id)[[UIColor lightGrayColor] CGColor]];
    CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)colors, locations);
    CGColorSpaceRelease(colorSpace);  // Release owned Core Foundation object.
    
    CGPoint startPoint = CGPointMake(0.0, 0.0);
    CGPoint endPoint = CGPointMake(CGRectGetMaxX(self.bounds), CGRectGetMaxY(self.bounds));
    CGContextDrawLinearGradient(ctx, gradient, startPoint, endPoint,
                                kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
    CGGradientRelease(gradient);  // Release owned Core Foundation object.
    
}

對象橋接類型

下表提供了一個支持Core FoundationFoundation之間橋接的數(shù)據(jù)類型的列表,同時列出了每一對數(shù)據(jù)類型開始生效的macOS版本。

Core Foundation type Foundation class Availability
CFArrayRef NSArray OS X 10.0
CFAttributedStringRef NSAttributedString OS X 10.4
CFBooleanRef NSNumber OS X 10.0
CFCalendarRef NSCalendar OS X 10.4
CFCharacterSetRef NSCharacterSet OS X 10.0
CFDataRef NSData OS X 10.0
CFDateRef NSDate OS X 10.0
CFDictionaryRef NSDictionary OS X 10.0
CFErrorRef NSError OS X 10.5
CFLocaleRef NSLocale OS X 10.4
CFMutableArrayRef NSMutableArray OS X 10.0
CFMutableAttributedStringRef NSMutableAttributedString OS X 10.4
CFMutableCharacterSetRef NSMutableCharacterSet OS X 10.0
CFMutableDataRef NSMutableData OS X 10.0
CFMutableDictionaryRef NSMutableDictionary OS X 10.0
CFMutableSetRef NSMutableSet OS X 10.0
CFMutableStringRef NSMutableString OS X 10.0
CFNullRef NSNull OS X 10.2
CFNumberRef NSNumber OS X 10.0
CFReadStreamRef NSInputStream OS X 10.0
CFRunLoopTimerRef NSTimer OS X 10.0
CFSetRef NSSet OS X 10.0
CFStringRef NSString OS X 10.0
CFTimeZoneRef NSTimeZone OS X 10.0
CFURLRef NSURL OS X 10.0
CFWriteStreamRef NSOutputStream OS X 10.0
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容