Swift 4 和 Objective-C 在同一个工程里的混搭编程的方法

Swift 4 和 Objective-C 在同一个工程里的混搭编程的方法,第1张

概述快速起步 你可以在 xcode 里同时使用 Swift 和 Objective-C(以下简称OC)来写代码,混搭编程的好处很多,比如允许大量代码的复用,在性能和开发效率之间找到平衡等。 在 Swift 中引用 OC 我们建立一个工程时,XCode会询问我们选择什么语言进行开发,如果你选择的是OC,那么当你第一次新建一个swift文件时,开发环境会询问你是否建立一个 .h 文件。这个 .h 文件命名 快速起步

你可以在 xcode 里同时使用 Swift 和 Objective-C(以下简称OC)来写代码,混搭编程的好处很多,比如允许大量代码的复用,在性能和开发效率之间找到平衡等。

在 Swift 中引用 OC

我们建立一个工程时,XCode会询问我们选择什么语言进行开发,如果你选择的是OC,那么当你第一次新建一个swift文件时,开发环境会询问你是否建立一个 .h 文件。这个 .h 文件命名方式是 "#Projectname#-BrIDging-header.h" 。你可以让开发环境帮你创建这个文件,也可以自己建,编译器只认这个文件名,只要别写错就好。

我们称这个文件叫桥接文件,它的作用是把OC代码选择性的暴露给swift,让swift可以调用这些接口。

暴露的方式是通过import,也就是说,你可以在这个 .h 文件里 import 任何你想要暴露给swift的代码,然后就可以在 swift 中访问了。

动手实践:

打开xcode,创建一个OC工程 HelloWorld

创建一个叫 HelloOC 的 OC 类,实现静态方法 hello,实现代码 NSLog("hello,OC.")

创建一个叫 HelloSwift 的 swift 类,继承NSObject,实现静态函数 hello(),实现代码 NSLog("hello,swift.")

这时候 xcode 会d出询问是否创建文件 HelloWorld-BrIDging-header.h ,选择是,如果你点了否,就自己创建一个

在 HelloWorld-BrIDging-header.h 代码里,加入 #import "HelloOC.h"

在HelloSwift 的 hello 函数里,在 NSLog("hello,swift.") 后追加 HelloOC.hello()


注意,继承自 NSObject 这点很重要,因为OC所有类都是继承自 NSObject,而 swift 没有这个要求,所以如果需要暴露 swift 的类给 OC ,一定必须是 NSObject 的子类才行。

如果编译成功了,那就说明编译器允许让你通过 HelloSwift 调用 HelloOC 的代码了。

这时候执行程序,会发现输出终端并没有打印任何东西。因为程序主体本身并没有调用 HelloSwift,我们建立的是 OC 工程,所以这时候就需要 OC 来调用 swift代码了。

在 OC 中引用 swift

当我们建立 HelloSwift 时,xcode 其实做了一些后台工作,除了询问你是否建立 "HelloWorld-BrIDging-header.h" 外,它还隐式的创建了一个叫 "HelloWorld-Swift.h" 的头文件,记住,这个文件是 xcode 隐式创建的,所以不要自己去建立这个文件,很多人查资料发现需要这个头文件没看仔细就自己去创建,结果导致各种编译不通过。

这个 HelloWorld-Swift 文件从文件到代码都是 xocode 动态生成的,你不需要编辑它,如果感兴趣里面到底写了什么,你可以通过 import 这个文件,Jump To DeFinition 的方式一探究竟。

当你需要暴露 swift 的类给 OC 调用时,你不需要通过任何逐个 import 的方式,你只要 import "HelloWorld-Swift.h" 即可。

尝试步骤如下:

在 VIEwController.m 文件中,引入头文件 #import "HelloWorld-Swift.h"

在 VIEwDIDLoad 方法的实现中,调用 [HelloSwift hello];

这时候编译,执行,工程打印日志输出为:

Hello,Swift.
Hello,OC.

框架(framework)的引用

开发项目经常要引用第三方框架,在 swift 中,引用这些框架是非常简单的,只要在 HelloWorld-BrIDging-header.h 中用 @import 语句包含该框架即可。不管该框架是用什么 swift 还是 OC 写的,又或者是混合编写,用法都一样。

而如果是用 OC 引用这些框架的话,标准做法应该是:

在 .m 文件中,用 @import 语句引用该框架

在 .h 文件中,如果需要在接口中声明对应的类,则应该用 @class 做前置声明,用这样的做法来规避循环引用问题。

举例 HelloWorld 项目来说,当我们要在 HelloSwift.swift 中引用一个 SwiftFrameWork 框架时,正确的做法是:

在 HelloWorld-BrIDging-header.h 中加入 @import SwiftFrameWork;

在 HelloSwift.swift 中自由调用 SwiftFrameWork 的类。

而如果要在 HelloOC.h 和 HelloOC.m 中这么做,则标准做法应该是:

在 HelloOC.m 中,通过 @import SwiftFrameWork;

在 HelloOC.h 中,如果有需要引用到的 SwiftFrameWork 框架中的类,用前置声明的方法解决,比如如果需要引用类 ClassA,则可以在引用前声明 @class ClassA;

如果需要在 HelloOC.h 中引用到 HelloSwift 类,也应该遵循步骤 2 的做法。

protocol (协议)

对于swift 的 protocol,也可以暴露给 OC 调用,但是需要做一些额外的工作,需要针对要暴露的 swift protocol 添加 @objc 声明,并且对于 optional 函数也要追加 @objc @optional

在 HelloSwift.swift 追加协议代码:

//因为这个protocol要暴露给OC用,所以用@objc声明@objcprotocolHelloProtocol{//这是一个普通的swift协议函数funcprotocolFunction()//这是个optional函数,需要在前面追加@objc声明@objcoptionalfuncoptionalProtocolFunction()}

一旦完成了以上 *** 作,OC类即可声明和实现对应的协议函数为其他类提供回调实现。

错误码

swift 和 OC 之间的错误码共享方案很简单,就是简单的命名映射技术,在 swift 中定义错误码如下:

@objcpublicenumCustomError:Int,Error{casea,b,c}

则 xcode 会在 HelloWorld-Swift.h 中声明对应的面向 OC 的错误码:

typedefSWIFT_ENUM(NSInteger,CustomError){CustomErrorA=0,CustomErrorB=1,CustomErrorC=2,};staticnsString*_NonnullconstCustomErrorDomain=@"HelloWorld.CustomError";

命名映射的规则比较简单明了,Enum 类型名不变,实例的名称通过大骆驼命名法进行拼接。


范例代码下载

HelloOC.h
HelloOC.m
HelloSwift.swift
ViewController.m

其它

苹果为保证 swift 和 OC 顺利交互,做了大量严谨的工作,这里就不一一说明了,毕竟道理大同小异,在需要的时候查阅文档就可以了,类似需要查阅的知识点有:

用 NS_REFINED_FOR_SWIFT 宏重定义 OC 接口

手动为 swift 类指定一个映射名给 OC 调用(通过 @objc)

通过 NS_SWIFT_name 指定 swift 自定义名称

...

参考资料

Using Swift with Cocoa and Objective-C (Swift 4)

author: Madaxin

email: madaxin@outlook.com

qq group: 527628370

home: madaxin.com

总结

以上是内存溢出为你收集整理的Swift 4 和 Objective-C 在同一个工程里的混搭编程的方法全部内容,希望文章能够帮你解决Swift 4 和 Objective-C 在同一个工程里的混搭编程的方法所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1061748.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存