Using Swift with Cocoa and Objective-C(Swift 3)--Working with Cocoa FrameWorks

原文地址:Working with Cocoa Frameworks

作为与OC交互的一部分,Swift提供了简单和高效的方式与Cocoa框架一起工作。

Swift自动将一些OC类型转换为Swift类型,以及自动将一些Swift类型转换为OC类型。能够在OC与Swift之间相互转换的类型被简称为桥接类型。例如,在Swift中,你可以传递一个String类型的数据给一个带有NSString类型参数的OC方法。另外,为了在Swift中看起来更自然,许多Cocoa框架,包括Foundation,AppKit和UIKit重新定义了他们的API。例如,NSCoder的decodeObjectOfClass(_:forKey:)利用Swift的泛型提供强类型签名。

Foundation

Foundation框架为应用程序和其他框架提供一些基础性的功能,包括数据存储、文本处理、日期和时间、排序和过滤、持久化以及网络相关功能。

桥接类型

Swift Foundation为如下的OC类型提供了对应的桥接类型:

这些Swift类型与其对应的类型有相同的功能。包含不可变和可变子类型的类族被桥接到同一个类型。Swift代码利用var和let去控制是否可修改,所以他不需要两种类。这些对应的类型能够像具有NS前缀的类一样被访问。

任何你可以使用桥接OC类型的地方,你都可以使用Swift类型来代替。这使得在Swift中你能够利用这些对应类型的功能。基于这个原因,在你的代码中你永远不需要使用桥接类型对应的类型。事实上,当Swift导入OC API时,导入器将OC中的这些类型进行了替换。同样的,当OC导入Switf API的时候,也做了替换。

类型关联其中最主要的一个好处是使得reason about your code很简单。获取更多关于值类型,参考Classes and Structures 和WWDC 2015 session 414 Building Better Apps with Value Types in Swift

如果需要使用桥接Foundation对象,可以使用as转换符来转换桥接类型。

Renamed Types

Swift Foundation重命名了类、协议以及一些相关的枚举和常量。

除以下几种特例,被导入的Foundation的类和协议去掉了NS前缀:

一些专门设计用来支持或者用于继承支持OC runtime的类,例如NSObject、NSAutoreleasePool、NSException、NSProxy

平台相关的类,例如NSBackgroundActivity、NSUserNotification、NSXPCConnection

有等价的Swift类,如桥接类型中描述的类

一些现在没有等价但是未来会有等价的类的一些类,例如NSAttributedString、NSRegularExpression、NSPredicate

Strings

Swift 桥接String和NSString。能够用as操作符将String转换为NSString,同样可以直接利用双引号创建一个NSString对象。

Numbers

Swift桥接NSNumber到Swift的算术类型,包括Int、Double、Bool。

可以使用as将Swift的算术类型转换为NSNumber。因为NSNumber能够包含多种类型,所以应该使用as?将NSNumber转换到Swift的类型,否则可能引发崩溃。同样也可以直接用浮点数、整数、bool值创建NSNumber类型。

Arrays

Array---NSArray。当桥接模板化的NSArray到Array时,转换会非常顺利。但是如果没有指定类型,那么Array中的类型将是[Any].

Sets

如果没有模板化,将是Set<AnyHashable>

Dictionaries

如果NSDictionary中没有模板化,将是[AnyHashable: Any]

Core Foundation

Core Foundation类型被导入为Swift类。当出现内存管理注释时,Swift自动管理Core Foundation中的对象内存,包括由我们自己实例化的Core Foundation对象。在Swift中,可以自由变换toll-free bridges Foundation和Core Foundation类型。同样如果你转换了bridging Foundation type,你也可以桥接一些toll-free bridged Core Foundation类型到Swift。

Remapped Types

当Swift导入Core Foundation类型时,编译器重新映射了这些类型。由于Swift本身是引用类型,编译器移除了每种类型结尾的Ref。

CFTypeRef统一映射为AnyObject类型。所以,当你需要使用CFTypeRef时,使用AnyObject。

Memory Managed Objects

在 Swift 中,从 annotated APIs 返回的 Core Foundation 对象能够自动进行内存管理--你不再需要调用自身的CFRetain,CFRelease,或者CFAutorelease函数。

如果你从自身的C函数和 Objective-C 方法中返回一个 Core Foundation 对象,为了自动引入内存管理,你需要用CF_RETURNS_RETAINED或者CF_RETURNS_NOT_RETAINED注释这个对象。同样你需要使用CF_IMPLICIT_BRIDGING_ENABLED和CF_IMPLICIT_BRIDGING_DISABLED包裹C函数声明,这使得Core Foundation?????

Unmanned Objects 未托管对象

当Swift导入未注释的APIs时,编译器无法对返回的Core Foundation对象进行内存管理。Swift使用Unmanned<Instance>包裹这些对象。那些间接返回的对象也是难以管理的。例如:

CFStringRef StringByAddingTwoStrings(CFStringRef s1, CFStringRef s2)

对应的Swift:

func StringByAddingTwoStrings(_: CFString!, _: CFString!) -> Unmanaged! {

// ...

}

当你从 unannotated APIs 接收了一个难以管理的对象,在使用它之前,你必须要将它转换为一个能够内存管理的对象。在这方面,Swift 可以帮你进行内存管理而不用自己动手。同时,Unmanaged结构也提供了两个方法来把一个难以管理的对象转换为一个可内存管理的对象--takeUnretainedValue()方法和takeRetainedValue()方法。这两个方法会返回原始的,开放的对象类型。您可以根据您实际调用的APIs返回的unretained或retained的对象,来选择哪一方法更合适。

比如,假设这里有一个 C 函数,这个函数在返回值前不会释放CFString对象。在使用这个对象前,您使用takeUnretainedValue()函数,以将它转换为一个能够内存管理的对象。

let memoryManagedResult = StringByAddingTwoStrings(str1, str2).takeUnretainedValue()

你也可以在一个非托管的对象中使用retain(),release()和autorelease()方法,但是这种做法并不值得推荐。

Unified Logging

统一的日志系统提供了一个API来捕获所有等级的系统信息,同时他也是NSLog的替代品。

os.log 

可以指定log的等级:Info、Debug、Error

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351

推荐阅读更多精彩内容