Tech

Objective-C引入Swift代码

2020-03-08  本文已影响0人  tom__zhu

OC与Swift混编项目中,如何在Objective-C代码中访问Swift的类型与声明?


概述

一般来讲,通过在Objective--C中导入Xcode生成的头文件(Xcode-generated header file)可以引用Swift中声明的类型。这个文件是一个Objective-C类型的头文件,其中包含了swift声明的接口,你可以认为这是一个swift对外暴露的头文件。而且这个Xcode生成的头文件(Xcode-generated header file)无需开发者做任何额外的事情,只是简单的导入到Objective-C中使用即可。
这个Xcode生成的头文件是以工程模块名称加上"-Swift.h"为后缀所构成。默认情况下工程模块名称就是工程的名称,需要注意两点:

  1. 名称中的非字母数字字符用下划线"_"代替。
  2. 以数字开头的工程名称,第一个数字被替换为下划线 "_" 。



    需要注意的是,Objective-C中引用Swift代码的操作会略有不同,具体取决于是在应用程序中导入引用还是在framwork中引用。

应用程序中导入

在应用程序中可以使用如下方法将Swift代码引入到Objective-C代码中:

#import "ProductModuleName-Swift.h"

默认情况下Xcode生成的头文件会包含Swift中以public或者open修饰的接口。假如程序中已经包含Objective-C桥接头文件,那么Xcode生成的头文件同样会包含以internal修饰的接口。使用private或者fileprivate修饰的方法则不会在Xcode生成的头文件中,并且不会暴露给Objective-C运行时,除非是通过@IBAction,@IBOutlet,@objc修饰的属性。单元测试代码中,可以访问internal修饰的声明,和用@testable加前缀是一样的效果。
需要注意的是,Xcode生成的头文件中swift包含了所有引用到的Objective-C类型,所以需要首先导入包含这些类型的Objective-C头文件。
最后,Xcode生成的头文件的工程模块名称是可以自定义的。具体方法是
Build Settings -> Objective-C Generated Interface Header Name

Framework中导入

有时你在编写一个Framework的时候也会出现OC和Swift混编的情况。在framwork开发中同样需要将Xcode生成的头文件导入到 ".m" 。
因为Xcode生成的头文件是framwork的publick接口一部分,所以只有被public或open修饰符修饰的声明才会被包含。使用internal修饰符标记并继承于Objective-C类中的方法和属性可以被Objective-C的runtime访问。然而,它们并不能在编译期访问以及不会出现在Xcode生成的头文件中。

在同一个框架中将Swift代码导入Objective-C方法:

  1. Build Settings -> Packaging -> Definies Module => Yes
  2. 在同一个garget中将Swift代码通过如下方法导入Objective-C .m文件
#import <ProductName/ProductModuleName-Swift.h>

在Objective-C头文件中前置声明Swift对象

在同一个target中,Objective-C头文件引用Swift中的类或协议会导致循环引用发生,为了避免产生这个问题,可以通过前置声明解决,实例代码如下:

// MyObjcClass.h
@class MySwiftClass;
@protocol MySwiftProtocol;

@interface MyObjcClass : NSObject
- (MySwiftClass *)returnSwiftClassInstance;
- (id <MySwiftProtocol>)returnInstanceAdoptingSwiftProtocol;
// ...
@end

swift中类和协议仅可在方法和属性类型中做前置声明。


总结回顾

应用程序中导入

参考链接
Importing Swift into Objective-C

上一篇 下一篇

猜你喜欢

热点阅读