Objective-C 与 Swift 混编之路

本文摘自: http://blog.csdn.net/mmoaay/article/details/48422309

本文内容基于 Xcode 6.4 和 Swift 1.2

重要资料

Using Swift with Cocoa and Objective-C 官方文档

为什么要混编?

  • 语言发展趋势(TIOBE),Swift 排行持续上升, OC 排行呈重力下降
  • 项目正常迭代需要 
    • 很多第三方库仍然使用 OC 实现
    • 项目中原来已经用 OC 实现的模块如果使用 Swift 重写,代价稍大
    • 我们需要在项目中使用 Swift 才能真正碰到问题,解决问题

注:不是为了混编而混编。混编只是在对开发资源、项目管理和技术发展趋势进行综合衡量之后做出的比较合理的选择。

如何开始混编?

步骤

  1. 创建工程,Language 选择 Swift 或 Objective-C 都可以。

  2. 创建 Swift 文件并添加 bridging header 文件

    添加 Swift 文件时 Xcode 会自动提示你添加 bridging header 文件,选择 Yes 即可

  3. 进行两处关键设置

     

    这两处设置 Xcode 默认都会设置好,可以把 Objective-C Bridging Header 和 Objective-C Generated Interface Header Name 改成自己想设置的名字。

至此Swift 与 Objective-C 混编的环境就算配置完成了。

XXX-Bridging-Header.h

如果需要在 Swift 中使用 OC 的代码或者库,只需要在这个文件中 import 相应代码或者库的头文件即可。

XXX-Swift.h

和 XXX-Bridging-Header.h 不同,XXX-Swift.h 文件不会出现在项目中,而是由 Xcode 自动生成,你可以在类似如下的路径下找到相应项目的 XXX-Swift.h 文件:(PS:演讲时没有写到PPT里面,实在抱歉)

/Users/perry/Library/Developer/Xcode/DerivedData/XXX-bhlzdinkujybftbjmgwjwclndmss/Build/Intermediates/XXX.build/Debug-iphonesimulator/XXX.build/Objects-normal/x86_64/XXX-Swift.h
  • 1

如果需要在 OC 中使用 Swift 代码,在使用的文件中 #import XXX-Swift.h (PS:其他一些在 OC 中使用 Swift 代码的注意事项会在后面详细说明)

查看 XXX-Swift.h 文件中的代码:

不难发现这个文件中的内容其实是将 Swift 中的代码转换成了 OC 的代码。

注:如果对项目进行清理操作,这个文件也会被删除,而且在重新构建的过程中,只有在所有的 Swift 代码都编译通过的情况下才会重新生成这个文件。

结合框架的混编

踩坑时间

OC 中的复杂宏

Swift 编译器不包含预处理器。取而代之的是,它充分利用了编译时属性,生成配置,和语言特性来完成相同的功能。所以对于上述类似的宏定义,建议用方法重新封装一次使用。

OC 中的宏和 Swift 中的类同名

因为 Swift 不能使用 #define,而 OC 可以,所以你可能会在 OC 中定义一个和 Swift 中类同名字的宏,如果你从来没有在 OC 中使用 Swift 代码提供的功能(也就是从来没有 #import XXX-Swift.h),编译时不会有任何问题,但是如果一旦使用了,就会报如下的错误:

这里是因为我使用 #define MView (@"MView") 将 MView 定义成了 NSString 类型的宏,而在 Swift 中 MView 是 UIView 的子类,在 #import "MDemo-Swift.h" 之后, MView 就被重复定义了,从而导致错误。

更新:如果 OC 中的类和 Swift 中的类同名,也符合上述情况。

Swift 使用 OC 中的枚举

  • 如果只是单纯使用值,可以直接使用枚举
  • 如果需要对枚举值进行运算,则需要使用 .value

OC 使用 Swift 中的枚举

  • 需要在 Swift 的枚举定义前加 @objc 修饰符
  • 枚举的类型必须是 Int

@objc / dynamic / NS*

  • 如果 Swift 类需要在 OC 中使用,建议继承 NS* 系列的类
  • 如果 Swift 类中的成员或者方法需要在 OC 中使用,使用 @objc 修饰符
  • 如果 Swift 类中的成员需要支持 KVC/KVO,使用 dynamic 修饰符

IBOutlet vs IBOutletCollection

Swift 中没有 IBOutletCollection ,而是如下的方式实现  IBOutletCollection

@IBOutlet var labels: [UILabel]!
  • 1

这个 IBOutlet 在 xib/Storyboard 中的情况如下:

需要注意的是:和 OC 的 IBOutletCollection 不同,labels 中的元素不一定是按照 black,white,blue,green 的顺序排列!

重复包含

OC 中可能会碰到 A 类头文件需要包含 B 类头文件,B 类头文件同时也需要包含 A 类头文件的情况,这个时候用 @class 即可解决问题。但是当 OC 中的 A 类头文件需要包含 XXX-Swift.h,而 XXX-Bridging-Header.h 中又 import A类头文件,这个时候就比较尴尬了。看下面的例子:

上面例子的情况是这样的:

首先,我们有两个 Swift 类 MManager 和 MData。 一个 OC 类 ViewController 。

然后,MManager 类中的一个方法需要传入 ViewController 类实例的句柄,然后把一个 MData 类实例赋值给 ViewController 类实例中的成员变量 mData(这个 mData 的类型是 MData )。

在这种场景下,就会出现重复包含,因为已经有了 MManager 类中的一个方法需要传入 ViewController 类实例的句柄 这样一个条件,所以我们必须在 XXX-Bridging-Header.h 中 #import "ViewController.h",这样我们就只能通过在 ViewController.m 文件中去 #import "XXX-Swift.h" 的方式来避免重复包含。此时我们需要将成员变量 mData 定义为 id 类型,当在ViewController.m 文件中具体用的时候再将其强制转换为 MData 类型。如下:

即可解决重复包含的问题。

这样的处理方式存在的问题是成员变量 mData 可以接受任何类型,所以我们在使用的时候要判断一下 mData 是否是我们需要的数据类型,这里我们介绍一下怎么判断 Swift 的 AnyObject 和 OC 的 id 是什么类型:

OC:

if ([self.mData isKindOfClass:[MData class]]) { // 如果 self.mData 不是 MData 类型,判断不成功
}
  • 1
  • 2

Swift:

if let data = self.mData as? MData { // 如果 self.mData 不是 MData 类型,判断不成功
}
  • 1
  • 2

properties

如果 OC 的类导入到 Swift 中使用,类的 properties 会有如下变化:

  1. Swift 中的属性都是 noatomic 的,所以 OC 类中的 atomic 将会失效
  2. OC 类中重写的 getter/setter 方法都将失效

Hello! Swift 2

var -> let

相比 Swift 1.2,Swift 2 强烈要求将在本方法体中值不会改变的量声明为常量,否则会出现 warning,所以在编写 Swift 1.2 的代码时,可以提前注意这一点,从而减小转换成本。

println

Swift 2 中这个方法被删除,不要使用。

do/while -> repeat/while

因为有变化,所以建议用 for / for…in 代替

面向协议编程

从 Swift 2 开始,我们可以对协议进行扩展,从此正式开启了 Swift 的面向协议编程时代。因为目前还没有在项目中具体使用,所以研究不是很深,大家可以参考下面三篇译文:

Swift 2:面向协议编程

如何正确使用协议

Swift 2.0 中的面向协议的MVVM

时间: 2024-12-09 12:25:33

Objective-C 与 Swift 混编之路的相关文章

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

Swift 2.0和Objective-C2.0混编之第三方框架的使用 swift 语言是苹果公司在2014年的WWDC大会上发布的全新的编程语言.Swift语言继承了C语言以及Objective-C的特性,且克服了C语言的兼容性问题.Swift语言采用安全编程模式,且引入了多种新功能,使得编程工作更加简便,灵活! 2015年6月9日苹果又一次给所有开发之者带来了一个惊喜,那就是今年年底swift讲开源,者队iOS开发着来说无疑是一个值得兴奋的消息,可是就在这短短的几个月里面swift吸引了越来

[ios][swift]swift混编

参考:http://www.tuicool.com/articles/QZNrErM 即使你尽量用Swift编写iOS程序,难免会遇到部分算法是用C++语言编写的.那你只能去问问”度娘“或“狗哥”怎么用 Swift 调用C++算法. 一,C,C++, Objective-C,Swift有什么关系,还有什么是混编 -.-? 1. 当然是兄弟关系,虽然Objective-C是扩充C的 面向对象 编程语言,C++是在C语言的基础上开发的一种通用 编程语言 .Swift是由苹果公司推出有意让其与Obje

OC跟Swift混编

OC项目中使用Swift 本文版权归作者所有,如需转载请联系孟祥月 CSDN博客:http://blog.csdn.net/mengxiangyue  独立博客:http://mengxiangyue.com 最近公司的项目开始计划使用Swift,由于原先的工程都是使用OC编写的,不可能一下全部转换成Swift,所以采用OC与Swift混编的方式是最好的选择.这篇文章只是一个简单的介绍,并没有太高深的知识. 我新建了一个演示的OC工程,当然你可以使用你已经存在的OC的工程.如果我们想要在OC工程

obeject-c 与 swift 混编

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px ".PingFang SC"; color: #454545 } p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px "Helvetica Neue"; color: #454545 } span.s1 { font: 12.0px "Helvetica Neue" } span.s2 {

初探swift语言的学习笔记九(OC与Swift混编)

swift 语言出来后,可能新的项目直接使用swift来开发,但可能在过程中会遇到一些情况,某些已用OC写好的类或封装好的模块,不想再在swift 中再写一次,哪就使用混编.这个在IOS8中是允许的. 先中简单的入手,先研究在同一个工程目录下混合使用的情况. 为了演示.先准备两个类 第一个是swift语言写的类,文件名为 act.swift import Foundation class Act : NSObject { func hasAct(tag:Int) -> String { swit

Swift语言学习之OC和Swift混编

本文转自http://www.helloswift.com.cn/swiftbase/2015/0112/3469.html iOS OC和Swift混编 1.创建一个swift或者oc的工程:我这里是创建的Swift语言的工程,工程名SwiftTest 2.在工程中代码目录下创建一个oc的类,选择oc语言, 会出一个对话框,选择YES          3.这时会在工程里看到下图这样一个头文件           4.在这个头文件里添加你的OC文件的.h文件,就可以在任意swift文件中自行调

关于oc和swift混编 框架framework时 只能在真机运行或只能在模拟器单独运行的解决方案

问题描述: 关于oc和swift混编 框架framework时 只能在真机运行或只能在模拟器单独运行的解决方案. 问题提供者:by 走跑 解决方案: 首先制作swift版本的framework(Cocoa Touch Framework)取名FirstMixed 1. 工程里面新建一个SwiftView.swift文件,继承UIView,class必须是public修饰 2. 生成真机和模拟器通用的FirstMixed.framework参考这篇文章的制作通用动态库部分,这里面有教如何生成真机和

Objective-C 和 Swift 混编项目的小 Tips(一)

本文主要闲聊一些 Objective-C 和 Swift 混编项目带来的一些潜规则,希望能帮到对此感到疑惑的朋友.下面我们开始进入主题: 命名 官方 Guide 上只是简单叙述(Using Swift with Cocoa and Objective-C),即 Swift 编译器会在我们使用 Objective-C 的 API 时自动的将其转成 Swift 风格的 API(说白了就是会对一些方法名.枚举名等等做一些有规则的删减,即重命名). 单例方法命名 在 Swift 中引用 Objectiv

swift混编oc碰到的问题

在swift中混编苹果官方的Reachability OC文件. 因为swift工程的target是生成framework而非app,framework中调用oc与app中使用桥接文件还不一样,参考: http://blog.csdn.net/cooldragon/article/details/50172649 主要步骤为: 1.将Reachablity.m 和.h文件加入到工程中 2.在ESPlus.h 中最后加上 (ESPlus为Framework名称) #import <ESPlus/R