(转)Swift与Objective-C混编

原文链接:http://www.jianshu.com/p/084f2ca45007#

随着Swift的改进及Swift开源项目剧增,越来越多的Objective-C工程开始使用Swift混编,不管是在基于Swift工程中或者Objective-C工程中,Swift和Objective-C文件都可以无缝结合。本文首先介绍下Swift与Objective-C混编的基础;然后在第二节中,根据我实际项目中,将详细展开Swift和Objective-C混编需要注意的一些细节。

Swift调用Objective-C

Swift调用Objective-C文件比较简单。当在Swift工程中新建Objective-C文件或者在Objective-C工程中新建Swift文件时,Xcode会自动提示你是否创建bridging header桥接头文件,点击创建后Xcode会自动为你创建一个桥接头文件。
如图1-1、1-2所示,在基于Swift的SwiftProject工程中创建一个OCViewController时,Xcode会自动创建一个名为SwiftProject-Bridging-Header.h桥接头文件。

Swift工程中自动提示是否创建桥接头文件.png
Xcode自动创建的Swift-Bridging-Header.h桥接头文件

当然你也可以在Building Settings中自己设置桥接头文件(一般情况下我们会用系统默认生成的),如图1-3所示:


自定义桥接头文件

创建好Bridging Header文件后,在Bridging Header文件中即可import需要提供给Swift的Objective-C头文件,Swift即可调用对应的Objective-C文件。同时Xcode可以自动生成Objective-C对应的Swift接口。如图1-4所示,OCViewController.h对外提供了一些Public的属性和方法,点击Xcode generated interface后可以看到Objective-C转换为Swift后的Public接口。

Xcode可以自动将Objective-C转换为Swift接口

Objective-C源代码对应的头文件

// 宏定义
#define DefaultHeight 100.f
// 协议
NS_ASSUME_NONNULL_BEGIN
@protocol OCViewControllerDelegate <NSObject>
- (void)detailButtonDidPressed:(id)sender;
@end
@interface OCViewController : UIViewController
// 属性
@property (nonatomic, weak) id<OCViewControllerDelegate> delegate;
@property (nonatomic, strong) NSString *testString;@property (nonatomic, strong) NSArray *testArray;
@property (nonatomic, strong, nullable) NSArray<NSString *> *testArray2;
@property (nonatomic, strong) NSNumber *testNumber;
// 方法
- (void)testMethod1;
- (BOOL)testMethod2WithParam:(NSString *)aParam;- (NSString *)testMethod3WithParam:(NSArray *)aArray;
- (nullable NSString *)testMethod4WithParam:(nullable NSArray*)aArray;
@endNS_ASSUME_NONNULL_END

转换后对应的Swift interface文件如下

import UIKit
// 宏定义
public var DefaultHeight: Float { get }
// 协议
public protocol OCViewControllerDelegate : NSObjectProtocol {
 public func detailButtonDidPressed(sender: AnyObject)
}
public class OCViewController : UIViewController { 
// 属性
 weak public var delegate: OCViewControllerDelegate? 
public var testString: String public var testArray: [AnyObject]
public var testArray2: [String]? 
public var testNumber: NSNumber
 // 方法
 public func testMethod1()
 public func testMethod2WithParam(aParam: String) -> Bool
 public func testMethod3WithParam(aArray: [AnyObject]) -> String
 public func testMethod4WithParam(aArray: [AnyObject]?) -> String?
}

Objective-C类、协议、属性、方法、扩展、闭包等所有功能都可以无缝地被转换为Swift接口被Swift文件所调用。但是还是有些特别需要注意的地方,详细将在第二节中讲到
Objective-C中为了兼容 Swift,新增了三大特性Nullability、Lightweight Generics、__kindof,详细阅读
构造方法
循环引用 (weak & unowned)
基础类型转换 (String、Array、Int)
可选类型
枚举(NS_OPTIONS)
单例
值类型和引用类型
闭包
判等 (== 、 ===、类型判断)
调用Objective-C第三方类库
更多...

Objective-C调用Swift
Xcode会自动为Project生成头文件以便在Objective-C中调用。在Objective-C类中调用Swift,只需要#import "productModuleName-Swift.h"即可调用,Xcode提供的头文件以Swift代码的模块名加上-Swift.h为命名。在这个头文件中,将包含Swift提供给Objective-C的所有接口、Appdelegate及自动生成的一些宏定义,如图1-5所示。注意productModuleName-Swift.h在Xcode中是无法搜索查看的,只能从import中点击进去查看。

Xcode自动生成SwiftProject-Swift.h文件

在大部分情况下,Objective-C都可以无缝地调用Swift,但是由于Swift相对于Objective-C多了一些新特性,比如泛型、元组、枚举的等,所以Swift暴漏给Objective-C的接口多了一些限制,因此Swift只能暴露在Objective-C中有效的接口。
Swift与C交互
有时候我们在Swift中可能需要与C交互(如Core Graphics),Swift对此提供了有效的支持。
原始类型Swift提供了将Swift类型直接映射为C原始类型的“类C风格”类型。这些类型以C开头后跟C原始类型名。例如,bool -> CBool,unsigned long long -> CUnsignedLongLong。
指针类型指针类型需要一些描述信息。例如,const void* -> CConstVoidPointer, void* -> CMutableVoidPointer或者COpaquePointer(两者区别在于用于参数还是函数返回值)。指向某一类型的指针
类型化的指针可以用泛型语法CMutableVoidPointer<Type>,例如,Int* -> CMutableVoidPointer<Type>

Swift与C++交互
Objective-C能与C/C++很好的交互,目前Swift对C++的交互不是很好的支持(原因苹果认为C++是个很复杂的语言,与C++的交互性需要考虑很多东西,是件很长远的事情,至少在3.0及3.0版本之前Swift不支持),所以如果有些库需要与C++混编可以考虑用Objective-C作为桥接。
观点
在同一项目中同时使用Swift和Objective-C混编,意味着可用Swift的新的特性及多编程范式为Objective-C项目增加新的特性或者优化代码结构,也可以同时充分利用Objective-C runtime等一些黑魔法。Swift能够与Objective-C和Cocoa框架和平共处,同时对一些C语言的基础类型保持了兼容,Swift的兼容使得它更加强大和便利。一旦在工程中采用Swift和Objective-C混编,你完全不用担心之前已有的Objective-C代码和框架。下节将详细展开Swift和Objective-C混编的一些细节详细展开。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容