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 我的类: NSObject {
func 打招呼(名字: String) {
print("哈喽,\(名字)")
}
} 我的类().打招呼("小明")

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

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

这样,我们在 Objective-C 里就能调用 [[MyClass new] greeting:@"XiaoMing"] 这样的代码了 (虽然比起原来一点都不好玩了)。

另外,正如上面所说的以及在 Selector 一节中所提到的,即使是NSObject 的子类,Swift 也不会在被标记为 private 的方法或成员上自动加 @objc,以保证尽量不使用动态派发来提高代码执行效率。

如果我们确定使用这些内容的动态特性的话,我们需要手动给它们加上 @objc 修饰。

但是需要注意的是,添加 @objc 修饰符并不意味着这个方法或者属性会变成动态派发,Swift 依然可能会将其优化为静态调用。

如果你需要和 Objective-C 里动态调用时相同的运行时特性的话,你需要使用的修饰符是 dynamic

一般情况下在做 app 开发时应该用不上,但是在施展一些像动态替换方法或者运行时再决定实现这样的 "黑魔法" 的时候,我们就需要用到 dynamic 修饰符了。

在 KVO 一节中,我们提到了一个关于使用 dynamic 的实例。

关于 Swift 和 Objective-C 混用的一个好消息是,随着 Swift 的发展,Apple 正在努力改善 SDK。

在 Objective-C 中添加的 nonnull 和 nullable,以及泛型的数组和字典等,其实上都是为了使 SDK 更加适合用 Swift 来使用所做的努力,我们还是很有希望在不久的未来能够摆脱掉这些妥协和束缚的。

本文来自王巍的@OBJC 和 DYNAMIC

Swift和OC混编时, 关于@objc的作用的更多相关文章

  1. iOS开发之swift与OC混编出现的坑,oc中不能对swift的代理进行调用,不能访问swift中的代理,swift中的回调方法

    1. Swift与oc混编译具体怎么实现,这儿我就不重复讲出了,网上有大把的人讲解. 2. 在swift与OC混编的编译环境下, oc类不能访问swift创建类中的代理? 解决方法如下: 在代理的头部 ...

  2. iOS8开发~Swift(五)Swift与OC混编

    一.概要 首先看<The Swift Programming Language>中提到"Swift's compatibility with Objective-C lets y ...

  3. Swift与OC混编

    OC调用Swift的方法:添加 import "xxxx-Swift.h" 头文件即可 Swift调用OC的方法:需要建立桥接: xxxx-Bridging-Header.h 头文 ...

  4. swift c++ oc 混编

    http://www.tuicool.com/articles/QZNrErM iOS 里面 Swift与Objective-C混编,Swift与C++混编的一些比较 时间 2015-03-23 23 ...

  5. 在OC项目中实现swift与oc混编 相互引用

    --------------------------------------------------------Begin--------------------------------------- ...

  6. swift与OC混编高级教程之混编框架的创建和调用

    首先创建一个project取个名字叫“MyMixed”,选择iOS-framework&library-cocoa touch framework 然后在里面创建一个SwiftView.swi ...

  7. Swift和OC 混编

    1.首先创建一个Swift工程 2.导入或者创建一个OC文件(.h和.m) 3.再创建一个桥连接文件 4.然后文件样子为 5.在桥接链接里面导入头文件 6.通过targets->->bui ...

  8. swift与OC混编之调用函数

    在桥接头文件里#import oc的.h文件,整个swift工程都能使用该oc文件,在.h里暴露的方法都能被该工程使用 //oc文件 TestOC.h #import @interface TestO ...

  9. swift和 oc 混编2-备

    在Swift语言出现之前,开发iOS或OS X应用主要使用Objective-C语言,此外还可以使用C和C++语言,但是UI部分只能使用Objective-C语言. 选择语言 Swift语言出现后,苹 ...

随机推荐

  1. SqlServer 还原,备份 Sql脚本命令

    备份 USE master go ),); set @path='d:\backup\'; set @name=@path+'TsDb.bak'; Backup database TsDb To di ...

  2. 构建高可用web站点(四)

    首先我们来了解负载均衡的概念:英文名称为Load Balance,其意思就是将负载(工作任务)进行平衡.分摊到多个操作单元上进行执行,例如Web服务器.FTP服务器.企业关键应用服务器和其它关键任务服 ...

  3. 编写C# Windows服务,用于杀死Zsd.exe进程

    最近经常在我的xp系统进程中出现Zsd.exe进程.刚开始他占用内存不是很大.但是过了一段时间就会变成几百M 机器就会变得很卡,网上说Zsd可能是病毒.所以我就想要不写一个Windows服务,让他每隔 ...

  4. SPSS方差分析

    1.overall:一切的,全面地 单因素方差分析:分析--比较均值--单因素ANOVA.多因素方差分析:分析--一般线性模型--单变量. 单因素方差分析和单变量方差分析区别:单因素针对的是自变量(自 ...

  5. NTOPNG修改密码

    感觉这个有点妖,因为在两个实例上修改密码都失败了. 于是,从网上看看是怎么回事, 按以下步骤重置你想要的密码: 1,为密码生成MD5字串: echo -n "your_password&qu ...

  6. android 自定义titlebar

    首先,修改标题栏的宽度和背景,在style.xml中添加: <style> <item name="android:background">@drawabl ...

  7. 【HDOJ】5017 Ellipsoid

    简单地模拟退火. /* 5017 */ #include <cstdio> #include <cstring> #include <cstdlib> #inclu ...

  8. BZOJ 1034 [ZJOI2008]泡泡堂BNB

    1034: [ZJOI2008]泡泡堂BNB Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1757  Solved: 928[Submit][Sta ...

  9. CSU 1160 把十进制整数转换为十六进制,格式为0x开头,10~15由大写字母A~F表示

    题目链接: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82974#problem/A 解题思路: 将16进制的表示方法列在一个数组里面 ...

  10. Mustache.js语法学习笔记

    原文地址:http://www.cnblogs.com/flypig88/archive/2012/05/14/2497780.html 看了Mustache的github,学学其中的语法,做个笔记 ...