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

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

一个新的雅虎:雅虎主页改版 谷歌发布Google Glass最新视频 公开接受预定 微软Windows Blue结束半程开发 或今年8月推出 JavaFX即将开源,支持iOS与Android开发 趣味编程网Codecademy携手Twitter、Evernote、Box等推出系列API教程 开发者,别让任何人绑架你的工作节奏 REST Style来袭 LinkedIn开源Rest.li框架 [探讨] 是用jQuery框架还是自造车轮呢? 一周消息树:Java 你还会让多少人继续“受伤”? Chromebook Pixel,揭开谷歌云世界的大幕 惠普:第一财季净利12亿 同比仍在下滑 谷歌发布超高清触屏笔记本Chromebook Pixel 传谷歌正开发触屏Chrome OS笔记本 今年或上市 估值25亿 视觉社交网站Pinterest融资2亿美元 跨平台开发框架Xamarin 2.0发布 移动新趋势:扁平化设计 vs. 拟物化设计(上篇) 杂谈 App Store 之 HIG 与 Objective-C 为什么苹果三星将主宰智能电视未来? 罗永浩可爱多:Smartisan OS即将发布 春晚 VS. 移动应用:用户注意力统计报告 Twitter发布BootStrap 2.3版本! 面向对象编程从骨子里就有问题——看看名人大家是如何诋毁面向对象的 开发者及团队能从LibreOffice那里学到什么? 8000美元存储135TB数据:打造开源的存储硬件 Bing,每月27亿的有效搜索不及僵尸网络的一半 为什么说Amazon的James Hamilton是“可遇不可求”的? Facebook背后的数据团队 红帽将产品转移到Apache社区 Impala是如何提升3~90倍查询效率的? 云中保障数据安全及完整性必须防范的遗留问题 VMware推出移动性平台:VMware Horizon Suite oracle中long类型是什么类型? PB简单画图?保存到库表中? 用程序代码建立表结构的问题 怎么在状态栏中加入竖线分隔,而且调整字体的大小? 请高手帮帮我!!!! jbuilder4的enterprise setup需要weblogic51,但我的是weblogic6,应该怎样才能让jbuilder支持6啊? 关于数据库的并发操作 谁知道哪里有vb下载? 哪有可下载的AUTOCAD2000 如何用VB实现存折的打印???? 请教给TImage加滚动条的问题 我和她在一起的话,会开心吗 请大家看看这条语句有什么错? 关于isdn在win2000下共享的问题 各位水友,有力的出力,没力的看看,拜托 请从位高手帮小弟解决一个棘手的问题……………………多谢!!!!!!! ALLTEC(荔枝)兄弟,兄弟我接帖太快 :( 請這邊來. ★★★ 救命啊! VC 用ODBC访问 Access 数据库的问题 guo->你在www.linuxforum.net中叫什么?有个guoemail是你吗? 软件发布:市场摊位租赁管理系统Ver1.0 软件发布:量和单位转换软件(免费版) 软件发布:五笔快打 在listview中的各个记录listitem中,有没有双击记录的事件 软件发布:伏羲服装鞋业购销存管理系统 软件发布:进销存商务管理pcft-jxc 征集各地童谣.唤醒儿时记忆! 今天我请客! 有关vb调用excel的问题! 有没有关于BDE的单独的分发程序? VB中报表预览打印能不能实现象EXCEL中一样的“按比例缩放”?如何实现? 单机版流量统计 关于Delphi6的安装问题 动态计算公式怎么实现?? 常用的英文字体是什么? 在通信过程中怎样做到防监听、防篡改? 各位大虾现欲用java开发一套网上投票表决系统 应该看什么书?用什么开发工具?(一定给分!) 关于winsock的问题,急急 怎样使用VB6中TREEVIEW控件? 我真的要疯了! 这里有很多Delphi6的控件! 如何在ASP中传递多个参数?displaymsg.asp?page=1在后面我还想加另外一个参数 有没有喜欢画漫画的? 如何得到ActiveX控件的窗口句柄 请问mif文件格式以及、读写方法?高分求解 sco unix的root口令忘了,谢谢. 在PowerBuilder中使用Microsoft Web浏览器控件 ,这个控件在ole中怎么没有啊? 急盼有人答复!!!!!! 急!急!编译exe时出现:link errors提示 具体提示:create of executable file failed? 小笨笨一问 年年岁岁花相似,岁岁年年人不同 VC++初学者的几个大烦恼!(苦呀,谁来拯救我这个VC小兵?) 某工作如果由第一、二、三小队合干需要12天才能完成;如果由第一、三、五小队合干需要7天才能完成;如果由第二、四、五小队合干需要8天才能完成;如果由第一、三、四小队合干需要42 求2道数学题的解法1.已知非空集合A={(x,y)|(a*2-1)x+(a-1)y=15},B={(x,y)|y=(5-3a)x-2a}.若A∩B=空集,求a的值.2.已知集合A={x|x*2-4mx+2m+6=0,x∈R},B={x|x<0,x∈R},若A∩B≠空集,求实数m的取值范围.a*2表示a 用方程和式子做,最好再简单的讲一下方法.张师傅加工一批零件,原计划每天加工50个,为了提前10天完成,他实际每天加工75个,张师傅实际多少天完成任务? 我想要小学一年级上学期的数学题在哪里找 面积为49平方米的长方形的周长是多少?.注意是长方形,不是正方形 给个准确的数啊,还有解法 1.如图a、b,是学校游泳池的平面图.比例尺都是1:1000.请观察这两个游泳池,并计算这两个游泳池的实际面积.如果你去游泳,现a有40人,b有100人,你准备到那个池中去游泳?(两问皆需算式) 三个人同时吃3个西红柿,用了3分钟吃完,6个人吃6个西红柿需要几分钟吃完?(仅用加减法列个式子) 下列结论错误的是()A.长度之比为1:2:3的三角形是直角三角形B.三个边长之比为3:4:5的三角形是直角三角形C.三个边长之比为8:16:17的三角形是直角三角形D.三个角度之比为1:1:2的三 小学六年级语文,数学题,急啊!谁帮帮我.回答得好我会加分的.数学:找规律:4,2,1,2分之1,4分之1,(),(),() 8分之1,32分之1,4分之1,16分之1,(),(),()应用题:1,一个长方形的宽是7分之5 0952873641 3的前面第三个的后面第五位是几?到底多少呀 能不能讲下 5555555 某公司托运物品,质量为a(a 1.有一堆圆锥形的沙土,底面周长37.68m,高5m,把这些土在宽15.7m的路上铺4cm厚,可以铺多少米?2.一个圆柱形玻璃容器的底面直径为12cm,它的里面装有一部分水,水中浸没着一个高9cm的圆锥形铁块,当 小学六年级奥数题,帮帮忙,最好有过程,谢谢!菜园里西红柿获得丰收,手下全部的八分之三是,装满一些筐还多24千克,收完其余部分时,又刚好装满6框,求共收西红柿多少千克? 在RT三角形ABC中,角C=90度,AD平行BC,角ABE=2角CBE,求证ED=2ABBD把角ABC分为角CBE和EBA,BE延长到D点,AD平行与三角形ABC底边BC,ADB也构成一个钝角三角形另外,不能用三角函数做,只能用几何 有浓度为30%的硫酸溶液若干,加了一定量的水后,稀释成浓度为24%的硫酸溶液,再加入同样多的水后,浓度将变成百分之几?能不能给我再详细点、我一定给多分。 小学六年级奥数题 要过程的在第16届广州亚运会上,中国代表团取得了金牌第一的成绩.获得的金牌数比铜牌数的2倍还多3块,如果金牌再多1块,那么铜牌就是金牌的49%,银牌是金牌数的59.5%.问 问一个初二的数学题,要解法! ! !有一个三位数,现将最左边的数字移到最右边,则比原来的数小45;又知百位数字的9倍比去掉百位数字后形成的两位数小3,试求原来的三位数是多少?要具体的解 )六(3)班男生人数比女生人数少20%,该班女生人数是男生人数的百分之几?男生人数是女生人数的百分之几?(急、、、、、) 两段圆柱的体积之差是314立方厘米.若将它们分别削成底面是最大正方形的长方体,则两个长方体体积之差是多少立方厘米? 小学三年级一题有多种解法的数学题 三个不同的整数a,b,m之间有如下关系b×m=a,能否说整数a一定能被整数b整除?简要说明理由 实验室了有两个等高的容器,圆锥体容器的半径为9厘米,圆柱体容器的半径是6厘米,现在圆锥体容器装满水倒入圆柱体容器中,这是水深比容器的高度的6/7低3厘米,两个容器的高是多少厘米? 求助:三年级一道数学题的解法.有两个一样的信箴,如果一个信封里放1 张信纸,还剩50张信纸;如果每个信封放3张信纸,还剩50个信封.请问:有几个信封,有几张信纸?不要设未知数. 一张长方形铁板的宽是30cm,四个角各减去一个小正方形,做成一个高5cm的长方体容器,容积的300ml(铁皮厚度忽略不计),这张铁皮原来的面积的多少?(每一个数据怎么得来的都说清楚,我不懂) :用10张同样长的纸条粘贴成一条长51厘米的纸条.如果每个粘贴处都重叠1厘米,那么每张纸条长多少厘米? 今年的8月份有5个星期日,4个星期一,那么今年的8月1日是星期几?我的方法是从31是星期日,倒推到3号是第一个星期日,那么1号就知道了.请问有没有更简便的方法? 学校的仪器室地面长4米、宽3米,有边长30厘米的A种方砖每块5元和边长40厘米的B种方砖每块8元,在可以拼接的情况下,用哪种方砖密铺地面比较便宜? 1、一个长方体的长和宽都是5厘米,把它从长的中点截成两个相同的长方体后,得到的一个长方体表面积比原来大长方体表面积少120平方分米,原来长方体的体积是多少?2、两种商品的价格比试7:3 请帮忙解题:一个小学二年级的数学题2个小铅球比一个大铅球重1千克,8个小铅球比5个大铅球轻1千克,算一算,大小铅球各重多少千克?这是二年级的数学题,不能用方程解,但需要列出算式. ①一道应用题牙膏出口处直径为6毫米,小红每次刷牙都挤出1厘米唱的牙膏.这支牙膏可用30次.该品牌牙膏推出的新包装只是将出口处直径改为5毫米,小红还是按习惯每次挤出1厘米长的牙膏.这 1.某单位食堂一月内购买了三次大米,后两次购买数量是前一次的两倍,由于数量增加,每次加个都比前一次优惠10%,共用去2536.8元.如果下月一次性购买同样多的大米,可至少节约多少元?2.一个长 小学五年级数学奥数题的答案?1.( )÷12=1:( )=3/( )=0.5=( )%2.把0.13万改写成以“一”为单位的数是( ),读作( ).3.在括号里填上合适的单位名称.(1)一个鸡蛋重50 1)一汽车销售公司,今年2月份销售了300辆a型汽车,3月份销售a型汽车的数量比2月份下降了24%,预计4月份的销售要比3月份下降1.3个人百分点.问:4月份比2月份销售情况下降了百分十几?2)甲、乙 丙在计算除法(有余数)是,吧除数137写作173,商多3,余数相同.求正确德商和余数 1.边长为自然数,面积为105的长方形.不同的长方形共有几种? 1、一项工程,甲乙两队合做每天能完成全部工程的40分之9,甲队单独做3天,乙队再单独做5天后,可以完成全部工程的8分之7,如果由乙队独做,需要多少天可以完成?2、一项工程,甲乙两人合做4天后, 两人:A,B从甲地和乙地同时出发,相向而行.第一次相遇离甲地5千米,然后继续走.走到两地后立即返回,第二次相遇离乙地2千米.问:甲乙两地相距多少千米? 一辆汽车共载客50人,其中一部分人买A票,每张1.20元;另一部分人买B票,每张1.00元,售票员最后统计出所卖的A票比B票多收入16元.买A票的有多少人?绝对要有解法,带讲解的我可能会追加的!赶快, 几道小学五年级奥数题1、把一个小数的小数部分扩大4倍,这个小时就变成6.6,把这个小数部分扩大8倍,就变成例如9.2,原来这个小数是( )2、从1、2、3、4、5、6中选出四个数字组成一个四位 一辆车从甲地开往乙地,如果将车速提高20%,可以提前1小时到达,如果按原速行驶120千米后,再将车速提高25%,可以提前401分钟到达,甲、乙两地相差多少千米? 要把题目类型和解法写出来, 1、花生的出油率是30%,300千克花生可榨油多少千克?2、2.五年级2班今天有49人到校上课,出勤率为98%,全班共有学生多少人?3.风速在森林地带可比平原减低30%,如果风在森林地带速度每秒是4. 1、长72米的列车,追上长108米的货车到完全超过用了10秒,如果货车速度为原来的1.4倍,哪么列车追上到超过货车就需要15秒.货车的速度是每秒多少米?2、一座大桥长1275米,一列火车过这座大桥.从 一个羽毛球4元,一个乒乓球2元.买这些花了100元.如果把羽毛球都换成乒乓球,乒乓球都换成羽毛球,则需要花92元.原来买这些乒乓球和羽毛球各多少个? 几道小学五年级数学题1.办公桌抽屉的长是30厘米,宽50厘米,高15厘米.如果一张办公桌有2个这样的抽屉,做一张桌子需要木板( )平方米.2.“环球”牌涂料分大桶、小桶两中规格包装,大桶8升, 一列客车从甲城开往乙城,每小时行60千米,行了2小时后,从乙城往甲城开出一列货车,4小时与客车相遇,这时货车行了全程的3分之1,两城相距多少千米? 游乐中心内一个长方形游泳池,长25厘米,宽12.5厘米,深1.2厘米.如果用直径20厘米的进水管向游泳池内注水,水流速度按每分100厘米计算,注满一池水要多长时间? 一项工作,甲单独做要用10小时,乙单独做要用15小时,甲做完三分之一后,两人合作,还需要几小时完成? 请用算式答小李算长方形的体积时,误将宽多算了五分之一,高少算了四分之一,结果比正确答案少了40立方厘米,那么该长方形实际体积是多少?大家请用算式答!大家请不要回答的太深奥,我才 求助小学六年级寒假作业一道数学题解法甲、乙两人以匀速绕圆形跑道按相反方向跑步,出发点在直径的两个端点,如果他们同时出发,并在乙跑完100米时,第一次相遇,甲跑一圈还差60米时第二次 求十道五年级奥数题加答案题目短一点 小学(超难的)我国个人所得税规定;个人月收入超过800元的部分应缴纳个人所得税,超过部分中,个人所得税率为;超过部分 500元 501~1500税率 5% 10%叔叔上月的税后工资为1500元,他交纳了多少 求这2道数学题解法1:求f(x)=cosx-1/2cos2x的最大值(x属于R)2:求sin10°sin30°sin50°sin70°的值 急.写出详细的算式,不用解题思路.一、填空.(每空0.(1)800706502读作(),四舍五入到“万”位约是( ).(2)250平方千米=( )公顷 1又1/6时是( )小时( )分(3)1.2=72/( )=( )%.(4)一 甲乙二人分别从东西两村同时相向而行,第一次相遇于距东村36公里处.二人继续前行,至目的地后折返,在距东村54公里处第二次相遇.问::东西两村的距离. 求2道数学题的解法1:tan71+tan49-√3tan71·tan492:(1-tan17)/(1+tan17) + cos146/(1+sin34) 1.张大伯家有一堆小麦,堆成了圆锥形,张大伯量的其底面周长是9.42m,高是2m,这堆小麦体积是多少立方米?如果每立方米小麦的质量为700kg,这堆小麦有多少千克?2.小红去食品店买肉罐头,她看到有 ABCDE×ABCDE———————XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX———————XXXXXABCDE 求A+B+C+D+E=?A= B= C= D= E=ABCDE不可能是零 急求2道数学题的解法!1.一种书若定价每本10元,可盈利1/4,若想盈利2/5,则应定价为每本()元2.同一种商品,甲将原价降低10元后卖掉,用售价的10%作积累,乙将原价降低20元后,用售价的20%作积累, 要算式,不要方法6.某装订车间的三个工人要将一批书打包后送往邮局(要求每个包内所装书的册数同样多).第一次他们领来这批书的十二分之七,结果打了14个包还多35本.第二次他们把剩下的
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn