本文主要闲聊一些 Objective-C 和 Swift 混编项目带来的一些潜规则,希望能帮到对此感到疑惑的朋友。下面我们开始进入主题:

命名

官方 Guide 上只是简单叙述(Using Swift with Cocoa and Objective-C),即 Swift 编译器会在我们使用 Objective-C 的 API 时自动的将其转成 Swift 风格的 API(说白了就是会对一些方法名、枚举名等等做一些有规则的删减,即重命名)。

单例方法命名

在 Swift 中引用 Objective-C 单例时,如果单例方法包含于类名,则会出现编译错误,下面我们来看几个例子。

Example 1


@interface TXLocationManager : NSObject + (instancetype)manager; @end

TXLoginManager 类有一个单例方法命名为 manager,在 Swift 中引用 manager 方法时,会出现编译错误:

说白了,manager 方法已经废了。。。

Example 2

在 Example 1 的基础上,我们把单例方法的命名改一改:


@interface TXLocationManager : NSObject + (instancetype)shareInstance; @end

单例方法命名改成 shareInstance 后,编译通过了。至此,至少问题已经解决了,现在我们再简单看看是什么原因?为何 manager 方法无法引用,而 shareInstance 却可以引用呢?

Example 3

在 Example 1 的基础上,把 manager 单例方法名称改为 shareManager :


@interface TXLocationManager : NSObject + (instancetype)shareManager; @end

我们可以发现在 Swift 中引用时,shareManager 方法名被重命名为 share :

小结

至此,我们可以得出一个简单的命名潜规则:在 Swift 中引用 Objective-C 单例时,如果单例方法包含于类名,则会出现编译错误,准确的说,应该是如果单例方法的名称正好是该类名驼峰命名的后缀,那么在 Swift 中引用该单例方法时,会出现编译错误。

为何在 Swift 中引用 Objective-C 类的 API 会出现这种问题呢?官方 Guide 上时这样描述的:

The Swift compiler automatically imports Objective-C code as conventional Swift code. It imports Objective-C class factory methods as Swift initializers, and Objective-C enumeration cases truncated names.

因为 Swift 编译器在使用 Objective-C 的代码时会自动的将其转成 Swift 风格的代码,就是会对一些方法名、枚举名等等做一些有规则的删减。

There may be edge cases in your code that are not automatically handled. If you need to change the name imported by Swift of an Objective-C method, enumeration case, or option set value, you can use the NS_SWIFT_NAME macro to customize how a declaration is imported.

根据官方 Guide,上述的这种 case 属于 特殊的情况。那如何解决这种问题呢,Swift 提供了一个宏,专门处理我们遇到的这种 case —— NS_SWIFT_NAME


@interface TXLocationManager : NSObject + (instancetype)manager NS_SWIFT_NAME(shareInstance()); @end

这样,manager 该单例方法,当我们在 Swift 中引用时,会被重命名为 shareInstance。


let _ = TXLocationManager.shareInstance()

普通方法命名

有时候,我们在 Swift 中引用 Objective-C 中某个类的 API 时,方法名是可能会被重命名的,下面我们直接看例子。

类方法


@interface TXLocationManager : NSObject + (instancetype)managerWithCoordinateY:(CGFloat)y // Or
// + (TXLocationManager *)managerWithCoordinateY:(CGFloat)y @end

当该类的类方法返回自身类型的实例对象时,上述的方法会被重命名。应该这样引用:

// 方式一:
let _ = TXLocationManager.init(coordinateY: 9) // 方式二:
let _ = TXLocationManager(coordinateY: 9) // 错误引用方式,编译失败
let _ = TXLocationManager.manager(withCoordinateY: 9)

通过上述实践,我们可以发现类方法中的 manager 前缀会被删掉,而且变成了 Swift 中的 init 方法。如果该类的类方法不返回自身类型的实例对象呢?


@interface TXLocationManager : NSObject + (void)managerWithCoordinateY:(CGFloat)y; // Or
// + (NSObject *)managerWithCoordinateY:(CGFloat)y;
// + (CGFloat)managerWithCoordinateY:(CGFloat)y; @end

通过实践可以发现,在 Swift 中是可以这样引用的:


TXLocationManager.manager(withCoordinateY: 9)

这种方式的引用同我们一般的方法引用是一致的,无异同。

实例方法

实例方法的重命名规则与类方法有点相似,此处就不再详述了,感兴趣的朋友可以自己实践一下。(当然方法的重命名我们一般都可以通过 NS_SWIFT_NAME 来指定)

参考链接

How to call an Objective-C singleton from Swift?

Objective-C 和 Swift 混编项目的小 Tips(一)的更多相关文章

  1. OC与swift混编 #import "项目名-Swift.h"失效问题

    由于项目多个环境部署,每次改配置比较麻烦,所以线上环境一个TARGETS,内部环境一个TARGETS, 都知道oc和swift混编的时候,会生成一个'项目名-Swift.h'文件,这个文件是隐式的,需 ...

  2. obeject-c 与 swift 混编

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px ".PingFang SC"; color: #454545 } p.p2 ...

  3. [ios][swift]swift混编

    http://blog.csdn.net/iflychenyang/article/details/8876542(如何在Objective-C的头文件引用C++的头文件) 1.将.m文件扩展名改为. ...

  4. OC跟Swift混编

    OC项目中使用Swift 本文版权归作者所有,如需转载请联系孟祥月 CSDN博客:http://blog.csdn.net/mengxiangyue  独立博客:http://mengxiangyue ...

  5. Swift语言学习之OC和Swift混编

    本文转自http://www.helloswift.com.cn/swiftbase/2015/0112/3469.html iOS OC和Swift混编 1.创建一个swift或者oc的工程:我这里 ...

  6. iOS开发——技术精华Swift篇&Swift 2.0和Objective-C2.0混编之第三方框架的使用

    swift 语言是苹果公司在2014年的WWDC大会上发布的全新的编程语言.Swift语言继承了C语言以及Objective-C的特性,且克服了C语言的兼容性问题.Swift语言采用安全编程模式,且引 ...

  7. IOS --- OC与Swift混编

    swift 语言出来后,可能新的项目直接使用swift来开发,但可能在过程中会遇到一些情况,某些已用OC写好的类或封装好的模块,不想再在swift 中再写一次,哪就使用混编.这个在IOS8中是允许的. ...

  8. 【转】IOS --- OC与Swift混编

    群里大神发的网址,感觉有用就先收录了,暂时没时间看SWIFT,感觉代码简洁,但是可阅读性不是太高,有些代码让系统去判断类型,同样的,我们看代码的时候也得自己去判断类型,或许看多就习惯了,有时间再说吧, ...

  9. OC与Swift混编

    群里大神发的网址,感觉有用就先收录了,暂时没时间看SWIFT,感觉代码简洁,但是可阅读性不是太高,有些代码让系统去判断类型,同样的,我们看代码的时候也得自己去判断类型,或许看多就习惯了,有时间再说吧, ...

随机推荐

  1. spring @Autowired和jdk的@Resource区别

    当一个接口只有一个实例时,使用这两个注解的效果是一样的. 当含有两个实例时,非得使用 @Autowired 那么定义的引用类型必须和service实现类定义的名字相同,参照下图 定义第一个servic ...

  2. php 例子 如何转换ISO8601为 utc时间

    //firstpowertime "2017-01-02T13:22:22" 获取时间$firstpowertime=$list[$i]['firstpowertime'];//判 ...

  3. JS--我发现,原来你是这样的JS:面向对象编程OOP[3]--(JS继承)

    一.面向对象编程(继承) 这篇博客是面向对象编程的第三篇,JS继承.继承顾名思义,就是获取父辈的各种"财产"(属性和方法). 怎么实现继承? 我们的JavaScript比较特别了, ...

  4. [转]分布式消息中间件 MetaQ 作者庄晓丹专访

    MetaQ(全称Metamorphosis)是一个高性能.高可用.可扩展的分布式消息中间件,思路起源于LinkedIn的Kafka,但并不是Kafka的一个Copy.MetaQ具有消息存储顺序写.吞吐 ...

  5. LayoutInflater 三种获得方式

    LayoutInflater 作用是从外部加载一个xml布局文件. 获得 LayoutInflater 实例的三种方式: 1.LayoutInflater inflater = getLayoutIn ...

  6. java中的static和final关键字

    一:static 1)修饰成员变量: static关键字可以修饰成员变量,它所修饰的成员变量不属于对象的数据结构,而是属于类的变量,通常通过类名来引用static成员. 当创建对象后,成员变量是存储在 ...

  7. StringUtils工具类常用方法汇总2(截取、去除空白、包含、查询索引)

      在上一篇中总结了StringUtils工具类在判断字符串为空,大小写转换,移除字符或字符序列,替换,反转,切割合并等方面的方法,这次再汇总一下其它常用的方法. 一.截取   StringUtils ...

  8. Thinkphp导入外部类的方法

    相信很多人在使用TP时候都苦恼使用外部类各种不成功 下面为大家详细介绍下引用方法和注意细节 手动加载第三方类库 由于第三发类库没有具体的命名空间,所以需要使用以下几种方法手动导入 1.import方法 ...

  9. c语言贪吃蛇详解-2.画出蛇

    c语言贪吃蛇详解-2.画出蛇 前几天的实验室培训课后作业我布置了贪吃蛇,今天有时间就来写一下题解.我将分几步来教大家写一个贪吃蛇小游戏.由于大家c语言未学完,这个教程只涉及数组和函数等知识点. 蛇的身 ...

  10. SSL/TLS 握手过程详解

    在现代社会,互联网已经渗透到人们日常生活的方方面面,娱乐.经济.社会关系等都离不开互联网的帮助.在这个背景下,互联网安全就显得十分重要,没有提供足够的安全保障,人们是不会如此依赖它的.幸运的是,在大牛 ...