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

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

去除IE 10广告的两种方法 直接拿来用!最火前端开源项目(二) 工作变得简单又高效 试试这八个WebApp 移动周报:生于微信,疯狂猜图的推广经 DataTorrent 将数据分析速度从“实时”提升至“现在时” 华为FusionCube开启全球规模商用 黑暗架构:以最少时间完成系统升级并获客户认可的开发之道 Hadoop Summit 2013见闻:创业与Hadoop 2.0不可阻挡 Facebook的清洁能源改革——革命尚未成功,仍需努力 YARN或将成为Hadoop新发力点 主流编程语言属性一览(多图) 粉碎硬件复杂论:开发者不懂硬件运行的方式怎么可以?! 最新版Chrome OS加入Word和Excel编辑功能 直指微软 传诺基亚将购诺西全部股份,疑为出售手机业务做准备? 优秀技术领导者的修成之道 直接拿来用!最火前端开源项目(三) 第八届开源中国开源世界高峰论坛成功举办 曾经那些主流的API,而今风光已不再! Android 4.3本月9日亮相 新功能汇总 移动游戏的国际化运营技巧 Google的Janus与Facebook的McDipper:将闪存用于数据中心 拥抱开源还是坚守阵地:传统数据库供应商面临抉择 超棒的30款JS类库和工具 立场坚定:惠普仍然密谋回到智能手机市场 6月份浏览器份额:Chrome成市场份额增长最快浏览器 关于PHP的十大误解 你中了几个? 专访西电朱虎明:异构计算硬件架构呈现百花齐放 百家争鸣 GSMA行纪:各种神器、好玩的、好看的全搜罗 大数据初创企业WibiData将Hadoop“打包”,谷歌董事长施密特两次参投 赚钱不忘环保 苹果计划为数据中心兴建太阳能发电厂 深度解析:清理烂代码 请问GridBagConstraints(有源码) 如何动态更换列表控件前面的小图标? 关于记录修改 用sdk编程怎样加入toolbar? table里的查询字段为什么不会显示数据? c#与interbase请教 C语言的大小问题都在这里面? 不要编译,你猜猜这个程序会有几个类型匹配的警告? 不要编译,你猜猜这个程序会有几个类型匹配的警告? 高分解问,请教高手!关天GIS! 如何判断窗体中的某个控件是textbox控件?或判断窗体中textbox的个数? 如何调用返回不定字段个数的存储过程 那里能找到rational rose 有关FORM与ACCESS数据库的连接 如何使用photoshop把图像缩小到指定大小? 关于某种文件关联的问题 为什么用net send发送的消息有关不掉,点了好多次确定也没用。 怎么保存到数据库中?急急急! 电脑出问题了。 tomcat4.01+apache2.046组合问题:单个的都能运行,...可以加分.. %u的问题 如何调整对话框上工具栏的状态 关于query控件的一个问题 如何结束一个线程? FastReport怎么将没有记录的地方也画上格子??? 我的oracle9装上去之后怎么有7。2G那么大??并且还连不上MANAGEMENT SERVER只能独立启动??请指教!! Fastreport与quickreport那个更好用? 进者有分. 强烈要求铲除全国所有的收容所!!! 要用什么软件才能将CMOS参数备份到某个文件夹中? 请问怎么在建表代码里定义关键字? 请问把数据写入ListView控件内,有什么办法可以快点? win2k server dns 求助! 我在易趣上竞的一个数码相机,只要250元,但是只能拍26张相。我不知道是真是假? 一个搞不定的恶意网站 cout与printf的问题 没有路由怎样用一台服务器实现300台左右的电脑上网? ResultSet里读出数据的参数问题,马上给分 netvt(唯她 v1.1.1),进来拿你应得的分 如果我的程序中用了VFP,但是用户可能并没有装VFP,有什么好的办法直接替用户解决了这个问题,而不是提醒他自己去装 怎么保存到数据库中?急急急! 我用treeview显示数据库的数据,增加一条新记录后,要怎么样才能马上在treeview显示? 无法传值问题,高手急救!!!!!!!!! 在线等待:怎么为datagrid控件的某一格赋值? 请教如何在input上传筐里面限制文件类型? java的图形设计比如swing有前途吗?大家来讨论下,迷惑中。。。 计算机静电问题!! 错误在那里 请教批量update出错问题 请问串口方面的? QQ使用MFC42.DLL, 数据库的记录有文本、有图片、我想给它排成word样式的A4版预览、再打印如何实现 耐磨橡胶衬板主要厂家有哪些? 邱少云在牺牲时夺取的是什么 近五年来,青蛙(田鸡)肉走上餐桌,假如人们大量捕杀这种农田中的青蛙.这样带来的后果是( ).“假如人们大量捕杀这种农田中的青蛙.”中的这种农田是指:水稻,稻螟虫,蚯蚓,蛇,蜜蜂,野 仿写句子如一朵鲜花,点缀不出绚丽的春天 一朵鲜花点缀不出绚丽的春天.仿造例子,再写一句,与其格式相同. cf潘多拉角色有什么优点,比起灵狐怎么样? 下图:三个直径相等的圆.求阴影部分的面积占一个圆面积的几分之几? 一朵鲜花点缀不出绚丽的春天仿写 邱少云哪年牺牲的? wp手机是什么? 西方管理思想产生的背景是什么? We don't do much b()with foreign companies.首字母填空 如图三个直径相等的圆阴影部分的面积占一个圆面积的多少 一个物体放在一个斜面上,这时物体对斜面有压力吗 (生物)有人爱吃青蛙,为此便有人大量捕捉野生青蛙,这种做法会产生什么后果? 如右图:三个直径相等的圆.求阴影部分的面积占一个圆面积的几分之几 有些人爱吃蛙肉,为此便有人大量捕捉野生青蛙,这种做法会产生怎样的后果? 已知点a(1,0)和b(3,-1).若点m是y轴上一点,且满足△abm是直角三角形,则点m的坐标是 爱因斯坦的相对论简单来说究竟是什么 有些人爱吃肉,为此便有人大量捕捉野生青蛙,这种做法会产生怎样的后果? 如图,直线y=kx+6与x轴,y轴分别交于点A、B,△ABO等腰直角三角形. (1)求函数解析式.我会做2)已知点C(4,0),点P是线段AB上的一点,且△POC是以PC为一腰的等腰三角形,求点P的坐标 大家觉得WP系统手机的优点在哪? 圆O1的半径是2cm,圆O2的半径是5cm,圆心距是4cm,则两圆的关系是 A.相交 B.外切 C.外离 D.内切圆O1的半径是2cm,圆O2的半径是5cm,圆心距是4cm,则两圆的关系是A.相交 B.外切 C.外离 D.内切 宇宙飞船在月球着落,宇航员在登上月球后,在月面上用天平测物体的质量,结果是什么 你觉得手机WP操作系统怎么样最近喜欢上了WP操作系统 隐形飞机的隐形原理是什么?如何做到隐形? 海贼王超新星是什么意思 最新的WP手机操作系统怎么样,有什么新功能呀 隐形飞机为什么能隐形,的原理是什么? 超新星与新星有什么区别? 金鱼是卵生还是蛋生如题 金鱼是过卵生还是蛋生抚养后代的 已知两个圆的半径分别为3cm和5cm,并且两圆没有公共点,则两圆的圆心距的取值范围是 六月五日是世界环境日、老师号召同学们爱护环境,从每个人做起.如果你想提醒同学们保护好校园新栽的小草,你应该怎么和同学们说呢? 恐龙是怎样从我们的地球蛋生的呢? “有些人爱吃蛙肉,为此便有人大量捕捉野生青蛙,这种做法会产生怎样的后果? 英语翻译your father wants you to take a training,class on management skins,you are an wining,to do so your classmate persuades you to attend the training.帮个忙 在下追加财富 带2个负电荷的硫离子的化学式是什么 有些人爱吃蛙肉,为此便有人大量扑捉野生青蛙,这种做法会产生怎么样的后果 长大后我就成了你作文500字 综合知识抢答赛,答对一题加5分,答错一题扣2分.A学生共抢答了20道题,最后得分72分.他答对几道题? 那一天我忘不了 作文 英语翻译rt 3q 人生如絮,飘零在此万紫千红的春天.仿句例句:人生如絮,飘零在此万紫千红的春天.仿句:人生如————————人生如———————— 作文字数:500---600.. 长大后我就成了你 六下练习册P115页阅读答案 人生如絮,飘零在万紫千红的春天.相照应的句子 CF潘多拉好吗?我买了,到底有什么好处 请问大家"我被这件事情感动了"用英语如何翻译啊~口语化点的哦~ 失根的兰花第⑩段中 人生如絮,飘零在此万紫千红的春天 应当怎么理解 人们大量捕杀青蛙会产生怎样的严重后果? 三只蚂蚁一起走,中间的说我两边各一只,右边的说我左边有两只,左边的说我右边没有为什么? 人生如絮,飘零在这万紫千红的春天意思 大量扑抓青蛙,后果怎样? 独木不成林的后一句急 堆焊耐磨板和铸造哪个好为什么堆焊耐磨行性能好能说的具体点嘛!谢谢~ 人生如絮 飘零在此万紫千红的春天 什么修辞 从跳高 等分析我主要玩JU 哪些单位需要堆焊耐磨板 如果人类停止生育,但能长生,这个世界会怎样?长生的感念是:小孩永远是小孩,年轻人永远是年轻人,老人永远是老人,但都没有死亡但出现车祸或别人杀害也就是=世界上就少了一个人例:100-1=99, 如果大量捕杀青蛙,你觉得会造成怎样的后果.简答,100字以内. 新加坡女子因将房屋租给非法入境者涉嫌日自民党推动修宪 拟改投票年龄吸引激世界社会主义论坛:“三南一北”对社会罕见日全环食降临 肯尼亚欲借此提振旅科普:人情冷暖,源自情绪好恶77岁贝卢斯科尼被曝与28岁女友秘密日本众议院通过自卫队法修正案日大学毕业生3年内辞职率高 官方疑企安倍晋三警卫车队连续两天发生交通事故新加坡两名少年不满被人抱怨挥棍打人被美国迷你航天机“追梦者”试飞降落时滑日本将设国家安全局 拟任命民间人士担美一女子7年对残障男友不离不弃感动众美售P3C首架飞机抵台 马英九称与日10月百城住宅均价环比上涨1.24%北京今日重度污染 邢台唐山长春“爆表军艺宣传处:不清楚李双江身体情况 请志愿军战士与女学生相约战后见面 62手机模型热卖成“学生救星” 不怕被老共和党参议员:美国安局可能在监听奥巴三季度游客满意度浙江宁波居全国第四“西安好青年”评选揭晓女子凌晨跳江幸被救起发现火锅滥用添加剂 可拨12331投的哥成立“雷锋车队”承诺绝不宰客、拒华商生活馆冬日暖心回馈 橡木餐桌餐椅看看11家参评银行 各环节谁居榜首西安首个膜处理污水厂开建致一死一伤驾车逃逸 被抓后辩称撞了垃省地电投资控股开展文明帮扶中“百万大奖”老太被骗9万元陕西省军联创业商会成立开发商“一房两卖”住建部门两人被停职金融力量首批市民代表团、华商媒体代表团走进3感恩节 你向谁表达感恩?《火星救援 》全球票房冲击6亿为出气叫人给餐厅“清场”6名挑头者被红木专家作品限量定做 欧美家具只需3发现非法营运罚3000元放行 20多女司机开车门时撞倒孕妇最后一天报名 明天下午开始抢车抢iP
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘