说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

Swift与Objective-C的兼容“黑魔法”:@objc和Dynamic

HTML文档下载 WORD文档下载 PDF文档下载
Cocoa框架早已烙上了不可磨灭的OC印记,而无数的第三方库都是用OC写成的,这些积累无论是谁都不能小觑。苹果采取了允许开发者在同一个项目中同时使用Swift和OC进行开发的做法,但要想实现互通,又需添加哪些桥梁?

虽然说Swift语言的初衷是希望能摆脱Objective-C的沉重的历史包袱和约束,但是不可否认的是经过了二十多年的洗礼,Cocoa框架早就烙上了不可磨灭的Objective-C的印记。无数的第三方库是用Objective-C写成的,这些积累无论是谁都不能小觑。因此,在最初的版本中,Swift不得不考虑与Objective-C的兼容。


Apple采取的做法是允许我们在同一个项目中同时使用Swift和Objective-C来进行开发。其实一个项目中的Objective-C文件和Swift文件是处于两个不同世界中的,为了让它们能相互联通,我们需要添加一些桥梁。

首先通过添加{product-module-name}-Bridging-Header.h文件,并在其中填写想要使用的头文件名称,我们就可以很容易地在Swift中使用Objective-C代码了。Xcode为了简化这个设定,甚至在Swift项目中第一次导入Objective-C文件时会主动弹框进行询问是否要自动创建这个文件,可以说是非常方便。

但是如果想要在Objective-C中使用Swift的类型的时候,事情就复杂一些。如果是来自外部的框架,那么这个框架与Objective-C项目肯定不是处在同一个target中的,我们需要对外部的Swift module进行导入。这个其实和使用Objective-C的原来的Framework是一样的,对于一个项目来说,外界框架是由Swift写的还是Objective-C写的,两者并没有太大区别。我们通过使用2013年新引入的@import来引入module:

@import MySwiftKit;

之后就可以正常使用这个Swift写的框架了。

如果想要在Objective-C里使用的是同一个项目中的Swift的源文件的话,可以直接导入自动生成的头文件{product-module-name}-Swift.h来完成。比如项目的target叫做MyApp的话,我们就需要在Objective-C文件中写:

#import "MyApp-Swift.h"

但这只是故事的开始。Objective-C和Swift在底层使用的是两套完全不同的机制,Cocoa中的Objective-C对象是基于运行时的,它从骨子里遵循了KVC(Key-Value Coding,通过类似字典的方式存储对象信息)以及动态派发(Dynamic Dispatch,在运行调用时再决定实际调用的具体实现)。而Swift为了追求性能,如果没有特殊需要的话,是不会在运行时再来决定这些的。也就是说,Swift类型的成员或者方法在编译时就已经决定,而运行时便不再需要经过一次查找,而可以直接使用。

显而易见,这带来的问题是如果我们要使用Objective-C的代码或者特性来调用纯Swift的类型时候,我们会因为找不到所需要的这些运行时信息,而导致失败。解决起来也很简单,在Swift类型文件中,我们可以将需要暴露给Objective-C使用的任何地方(包括类,属性和方法等)的声明前面加上@objc修饰符。注意这个步骤只需要对那些不是继承自NSObject的类型进行,如果你用Swift写的class是继承自NSObject的话,Swift会默认自动为所有的非private的类和成员加上@objc。这就是说,对一个NSObject的子类,你只需要导入相应的头文件就可以在Objective-C里使用这个类了。

@objc修饰符的另一个作用是为Objective-C侧重新声明方法或者变量的名字。虽然绝大部分时候自动转换的方法名已经足够好用(比如会将Swift中类似init(name: String) 的方法转换成-initWithName:(NSString *)name这样),但是有时候我们还是期望Objective-C里使用和Swift中不一样的方法名或者类的名字,比如Swift里这样的一个类:

class 我的类 {    func 打招呼(名字: String) {        println("哈喽,\(名字)")    }}我的类().打招呼("小明")

Objective-C的话是无法使用中文来进行调用的,因此我们必须使用@objc将其转为ASCII才能在Objective-C里访问:

@objc(MyClass)class 我的类 {    @objc(greeting:)    func 打招呼(名字: String) {        println("哈喽,\(名字)")    }}

这样,我们在Objective-C里就能调用 [[MyClass new] greeting:@"XiaoMing"] 这样的代码了(虽然比起原来一点都不好玩了)。另外,正如上面所说的以及在Selector一节中所提到的,即使是NSObject的子类,Swift也不会在被标记为private的方法或成员上自动加@objc。如果我们需要使用这些内容的动态特性的话,我们需要手动给它们加上@objc修饰。

添加@objc修饰符并不意味着这个方法或者属性会变成动态派发,Swift依然可能会将其优化为静态调用。如果你需要和Objective-C里动态调用时相同的运行时特性的话,你需要使用的修饰符是dynamic。一般情况下在做App开发时应该用不上,但是在施展一些像动态替换方法或者运行时再决定实现这样的 "黑魔法" 的时候,我们就需要用到dynamic修饰符了。在之后的KVO一节中,我们还会提到一个关于使用dynamic的实例。

作者:王巍(@onevcat),iOS和Unity3D开发者。

本文转载自:Swifter

点击链接进入Swift技术社区,了解更多Swift开发的技术热点内容!


CSDN JOB移动工程师专场招聘,直击20家企业高薪职位-->http://job.csdn.net/event/mobdev.html

VB如何将程序建立成“启动”文件夹的捷径? VB如何将程序建立成「启动」资料夹的捷径。 VB如何结束 Shell 所启动的程序? VB如何拦截键盘输入 如何判定VB调用的一个EXE程序已经结束. VB如何判断某一个Drive是否为光碟机? VB如何清空回收站? VB如何取得汉字的区位码 VB如何去优化你的VB程序 VB如何让点阵打印机每次印出一行? VB如何设计一个可中断循环的按钮。 VB如何实现VB程序登录密码加密 VB如何使程序不出现在任务列表中 VB如何使键盘、Mouse失效(JournalPlayBack Hook) VB如何使用 DBGrid VB如何突破 TextBox 32K 的限制? VB如何为执行程序加上参数? VB如何压缩较长的全路径文件名中的路径 (Path) 字串长度? VB如何在VB中实现密码的读取 如何在VB中使用命令行参数 VB如何在内存中的指定位置取数据? VB如何在已经存在的文本的textbox添加新的一行 VB如何在資料庫中存入單引號? VB如何正确使用VB6访问Access2000数据库 VB如何自动记录计算机开机时间? VB如何做到当我们单击窗体的最小化和关闭按钮时,窗体先最小化到任务栏成为按钮,然后消失呢?金山词霸能 软件工程篇-Const与#Const的对比 -VB资料 软件工程篇-从Visual Data Manager开始 -VB资料 软件工程篇-理解错误处理代理 -VB资料 软件工程篇-清空集合内容的几种方法 -VB资料 软件工程篇-受限制的共享软件Shareware -VB资料 请问LOEBBS的系统占用时间 在Tomcat4.0环境下,运行JSP,程序出错? 向大家推荐一个品质计数计量图控制程序 来者有分,班长请高抬贵手,不删此贴,谢谢 谁知道哪儿有cloudscape数据库的安装程序? 老大,infopower2000的密码是多少阿? 100分求<壮志雄心>8-20集的下载 能讨论一下 VB开发财务相关软件的经验吗,各位高手??(UP都有分) 简单的问题,送分 请教:ADO方式连接Oracle数据库时出现:多步OLE DB错误,请检查每个OLE DB状态,怎么办? 错乱 如何用jdbc连接oracle 老大,infopower2000的注册号,密码是多少阿? 向大家推荐一个品质计数计量图控制程序,来者有分,班长请高抬贵手,不删此贴,谢谢 线程管理 向大家推荐一个品质计数计量图控制程序,来者有分,班长请高抬贵手,不删此贴,谢谢 能不能提供一些有关图像分割的算法和实现代码!谢谢 如何实现语音聊天技术~需要什么? 如何实现语音聊天技术?需要些什么 请问如何用delphi语言将一文件夹压缩? 老大,infopower2000的注册号,密码是多少阿? 我现在是2000系统,想装一个98系统而不破坏2000,请问有解决办法吗?谢谢! [求助高手]VB注册表的读取 (dave_adl)将军请进来啊!给你分啊! 谁有数据结构与算法的东西,我在技术区可以给分 局域网内收发邮件?? 怎样利用主键不可重复的特性? 在ACCESS中如何在中间插入记录呢? 有谁知道,jbuilder7.0是调用了那些命令打包成EXE文件的? 一个简单的问题 OpenDialog控件怎么初始化路径? 使用regsvr32 时怎样不显示成功的对话框(即参数?) 怎样提高专家分? 网关屏蔽了QQ、聊天,如何使用QQ和聊天 如何配置声卡? 使用Excel时为什么不能更新图表? 欢迎踊跃参加 Office开发技术网上竞赛 使用Excel时为什么不能更新图表? 有人熟悉中科红旗吗? 请教DataBufferFloat的问题,没什么我的文件说找不到 会不会出BCB6中文版啊 http://go3.163.com/21jsp/cn/com/lyfupload.htm 请问各位:你们怎样在程序中用SQL脚本来建表啊?!!不会是叫客户自已创建表吧? 请进来看看,关于CString和WFC编程的! 关于定义一个struct 的 array问题?帮忙阿 在一个线程内部怎样实现将该线程挂起? 帮我个忙好吗,有关数据库的(我是新手)(很急) 用gcc编译后提示:/tmp/ccn/I193.o: In function "main" ...... delphi的简单问题 关于文件操作 请教,关于网管理论,协议,开发等方面,该看什么书? 提倡:对贴不对人 如何在word 中链接excel 表格后,不让它随源文件更改而变,但有时又要改变其中数据,怎么做 一个代理服务器问题 避暑有哪些方法可以从食物等方面说说 有一堆钢管,最上层是10根,最下层是20根,每相邻上下两层之间相差一根,这堆钢管有几根? 电池的结构 避暑方法有哪些? 某钢管产的无缝钢管堆成梯形状.最上层有20根,最下层有40根,钢管共有21成.这堆钢管共有多少根?怎么求 在一水平地面上,一质量为20kg的物体受到一水平方向的拉力作用由静止开始向前运动,一段时间后撤掉这一拉力,物体由静止开始运动的v-t图象如图所示, .求:(1)该物体与地面的动摩擦因数 货场的一些钢管堆成一个梯形状,一共放了8层,最上面一层是9根,相邻两层都差1根,最下面一层有16根,这堆钢管一共有多少根? 小强在杭州将一根质量分布均匀的条形磁铁用一条线悬挂起来,使它平衡并呈水平状态,以寻找南北方向.悬线系住的位置在 为什么? 质量为10KG的物体在50N的水平拉力作用下,由静止开始在水平做匀加速直线运动,质量为10KG的物体在50N的水平μ=0.2 1.当速度达到2m/s时,水平拉力的瞬时功率?2.合力的功率为多大?(g=10m.s2) 一堆钢管,最上层4根,最下层10根,相邻两层均差1根,这堆钢管共多少根 小强在北京将一根重量均匀的条形磁铁用一根细线悬挂,使其水平平衡,应系哪个位置 击实试验取样的是回填土还是原土请问:1、重型击实试验是在土方开挖完成以后(还未回填土)做还是回填完土后做?2、级配碎石需要做击实试验吗?重型还是轻型?如需做的话,那里取样?3、 质量为m的物体与水平面间的动摩擦因数为μ,现在用与水平方向成θ角的斜向上的力拉物体质量为m的物体与水平面间的动摩擦因数为μ,现在用与水平方向成θ角的斜向上的力拉物体,使物体沿水 条形磁体和铁条有什么区别?不都是铁吗?为什么只有条形磁铁周围有磁场,而铁条没有? 工程勘察中各类土层(淤泥、粘土、粉土、砂、砂砾石、回填土等)的比重、剪切波速度范围 据法医证实此人已死用 用英语怎么说? 杠杆中F1 F2 F3代表什么?我只知道F1是动力,F2是阻力,就是不知道F3是啥来的? 谁能帮我算下环刀取样土壤含水率?A:湿457.75克 干410克B:湿422.5克 干383克 如图所示,质量为20kg的物体放在水平地面上,已知物体与水平地面间的动摩擦因数为0.3,现给物体施加一个与水平面成37度角的斜向上的拉力F1=50N的作用,则物体受到的摩擦力为多大?要使物体恰 将两个完全相同的条形磁铁颠倒两极组合成一个磁体后,这个新磁体有无两极?四个条形组合呢? 电池是由什么构成的 ,一根长度为50cm的木棒的两端系着一根长度为70cm的绳子,现准备在绳子上找一点,然后将绳子拉直,使拉直后的绳子与木棒构成一个直角三角形,这个点将绳子分成的两段各有多长 10分钟解答出 6.小芳在北京将一根质量分布均匀的条形磁铁用细线悬挂起来,使它在水平位置平衡,悬线系住磁铁的位置应该在 A.磁铁的重心处. B.磁铁的某一磁极上. C.磁铁重心的北侧 D. 电池是由什么组成的?电池组成的部分及成分有哪些? 把一条绳子拉直就成了一条线段, 如图,已知OC平分∠AOB,OA=OB,PD⊥AC于D,PE⊥BC于E,求证PD=PE(急呀!只限今天) 初三物理常识问题考卷上的一张图.(叫我们补充画图,本图还未画)没有什么错误么?电源负极出来后接到灵敏电流计G负接线柱上居然和电压表正接线柱连起来叻? 工地运来一些钢管,堆成梯形状,每相邻两层之间相差2根.已知顶层摆了12根,底层如果7a-6b=0(a,b不为0),则a和b这两种量成()比例,比值是()。 O为支点,OA长为L,F1,F2,F3,F4为作用在A点的四个力.(1)算出F1,F2,F3,F4的力臂的长度,并比较它们的大小;(2)在杠杆OA上的哪一个点,沿什么方向施加作用力,该力的力臂最长,长度为多少?(3)在杠 刚买的绿源电动车,第二次充电,充电器指示灯就显示电池维护,怎么办?第一次充电没事,第二次就电池维护的灯亮了,充满的灯也亮,知道的高手说说吧, 绳子只要受力就能拉直吗? OC平分∠AOB,P是OC上一点,D是OA上一点,E是OB上一点,且PD=PE,求证∠PDO+∠PEO=180 电动车充电器充电指示灯一红一绿怎么回事?我的充电器有时正常的显示红灯,有时就会一红一绿(这样就冲不进电了),好像我的充电器接触不正常吧,但又不知道怎么处理?我拿我婶婶的充电 将重物挂在绳子中央,两个人用力拉绳子,绳子能拉直吗?为什么? 在条形磁铁周围放一些小磁针,以下说法正确的是( )A.同一固定点放人不同的小磁针其指向性发生 改变 B.不同点的小磁针指向完全相同 C.同一固定点放入不同的小磁针,静止后小磁针 指向 电动车充电器指示灯一直闪烁我的充电器一插上电源两个指示灯一闪闪的.而且不能充电. 请教高手指导.充电器的那个部位元器件出问题.? 弹力做功表达式也是 w=1/2kx^2吗? 一个静止在粗糙的水平面上的物体质量为10千克,受到水平向右的50V拉力作用,那么摩擦力因素为0.1 g=10m/s2 动滑轮实质是一个动力臂是阻力臂()的杠杆,使用动滑轮时能省()力,但费() 如图OC平分∠AOB,P是OC上一点,D是OA上一点,E是OB上一点,且PD=PE,求证∠PDO+∠PEO=180添辅助线,我只是初二上的,没教过的性质别用 条形磁铁中心的磁感线怎样从N极回到S极 动滑轮实质是一个动力臂是阻力臂什么的杠杆使用动滑轮时能省什么力,但费什么 OC平分∠AOB,点D,E分别在OA,OB上,点P在OC上,且有PD=PE,求证∠DPO=∠PEB 为什么条形磁铁的外部磁感线是由N到S,内部就成了S到N了呢? 请高手用电子表格编一个实现如果 1就返回杂填土,2就返回素填土,3就返回粘土,4就返回粉质粘土,5就返回粉土,6就返回淤泥,8就返回细砂,9就返回中砂,12就返回松散,根据数字的不同返回不同的 如图,OC平分角AOB,点D,E分别在OA,OB上,点P在OC上,且有PD=PE,求证:角PDO=角PEB. 如图,OC是∠AOB的平分线,P是OC上的一点,PD⊥OA于点D,PE⊥OB于点E.M,N分别是OA与OB上的一点,DM=EN,连接PM,PN.求证:PM=PN 1、某场地平整有6000 m3的填方量,需从附近取土填筑,其土质为密实的砂粘土,已知Ks=1.05 ,K‘s=1.05 试求:1)填土挖方量 2)已知运输工具斗容量为2 m3,需运多少车次. 滑动摩擦力一定是阻力吗 为什么说磁铁周围的磁感线都是从N极出来进入S极,在磁体内部磁感线从S极到N极?是不是科学家随便规定的? 弹簧弹力和弹簧伸长量的实验中,图像上端为什么会变成曲线? 滑动摩擦力只能作为阻力 磁感线都是从N极出来进入S极对嘛?拿条形磁铁说中间不也有磁感线发出嘛? 请问下面的图中,若小物块向下移动x,则各弹簧伸长量是多少? 我的心已死 用英语怎么说?谁能告诉我用英语怎么说啊? 当细绳上的A点以速度v水平匀速向右运动时,问橡皮E的速度情况是A 橡皮E的水平速度为vcos0 B 竖直方向速度为vsin0C 速度大小为V D 橡皮速度方向与水平方向夹角为0 建筑工地有一堆钢管,最底层有26根,每向上一层就少一根,最上层有18根.这堆钢管一共有多少根? 大象已死用英语怎么说 在一个匀速运动小车内用一绳悬挂一小球,小车突然停止的瞬间,为什么说小球此时处在圆周运动的最低点?绳不是可以突变吗? 锂电池构造问题请问哪里用到了胶带,我记得胶带的作用好像是有2个,绝缘和高温,请问锂电池哪里用到了这2个作用的胶带?或者其他见解
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘