OC和Swift混编

OC和Swift的混编,分为两种情况:

  • OC项目中嵌入Swift文件
  • Swift项目中嵌入OC文件

先来看OC项目中嵌入Swift文件的情况

新建一基于OC的项目,比如:OC_project

接下来我们创建一个Swift类:BridgeTest.swift,并在里面新建一个类:Person

-- Person.swift --
    
import Foundation

// public可以省略,外面同样可以调得到
// 要OC调用到这个Swift类,则@objc不可省略,另外要直接或间接继承于NSObject
@objc public class Person: NSObject { 
    // 为了让OC调用,方法同样需要@objc标示
    @objc
    func think() -> Void {
        print("person can think, it's important.")
    }
    
    @objc
    func eat() -> Void {
        print("person can eat, it's important.")
    }
    
    @objc
    func drink(_ water: String) -> Void {
        print("person can drink \(water), it's important")
    }
}

注:这里的Swift文件名叫BridgeTest.swift,而类名叫Person, 这并不是一个好的命名习惯,一般文件名和类名可以统一,在此写成不一样,是为了说明这和Java并不一样,在java中一个class被命名为public的,则此文件名必须和此public的类名相同,但swift中并没有这个限制。

在新建这个Swift类时,Xcode会提示生成桥接文件:


1.png

这个桥接文件的作用主要是在Swift中调用OC的,我们暂且不理会,照提示确定即可。这会生成文件OC_project-Bridging-Header.h

然后我们在OC的类里面调用这个Swift类:
#import "ViewController.h"
#import "OC_project-Swift.h" // 如果要使用Swift类,这个头文件需要添加,此文件是系统自动生成,不可见

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // 依赖于Apple自动生成的‘工程名-Swift.h’文件,本示例中是:OC_project-Swift.h
    // 其实在这个文件中声明了一些Swift到OC的转换后方法,因此我们可以以OC的调用方式调用Swift方法
    Person *p = [[Person alloc] init];
    NSLog(@"%@", p);
    [p think];
    [p eat];
    [p drink:@"咖啡"];
}

注意,一般这样做就可以了,但Xcode有时候会抽疯的,因此如果有问题我们需要检查Xcode的设置:

  • Defines Module : YES

    2.png

  • Product Module Name : yourProjectName

    3.png

    Make sure that your Product Module Name doesn't contain any special characters.

  • Install Objective-C Compatibility Header : YES

    4.png

    Once you've added *.swift file to the project this property will appear in Build Settings。

  • Objective-C Generated Interface Header : yourProject-Swift.h

    5.png

    This header is auto generated by Xcode

  • Objective-C Bridging Header : $(SRCROOT)/yourProject-Bridging-Header.h

    6.png

上面是让OC调用Swift方法,下面我们依然基于这个OC项目,让Swift调用OC,在做这个之前我们需要知道一个概念:

Objective-C调用Swift: 需要在暴露出来的Swift方法和属性上加@objc标识,否则不可用;且文件的类需要继承自NSObject或NSObject的子类。另外如果仍有问题,需要在工程配置里面做一些小改动。
Swift调用Objective-C: 需要在统一的bridge头文件(YourProjectName-Bridging-Header.h)里面import,然后即可使用。

在上面的示例中, 使用OC调Swift并不需要使用桥接文件, 但如果要让Swift调OC,则需要在这个文件中import要在Swift中使用的OC类的头文件。
接下来我们新建一个OC的Dog类,让Swift方法调用这个Dog类的方法。

-- Dog.h --
@interface Dog : NSObject

- (void)think;
- (void)eat:(NSString *)food;
@end

-- Dog.m --
@implementation Dog

- (void)think {
    NSLog(@"Dog can think, but it's different with person's think");
}

- (void)eat:(NSString *)food {
    NSLog(@"%@", [NSString stringWithFormat:@"dog can eat: %@, it's important", food]);
}

@end

然后在BridgeTest.swift中的Person类中添加两个方法:

@objc
func dogThink() -> Void {
    let dog: Dog = Dog()
    dog.think()
}

@objc
func dogEat(_ food: String) -> Void {
    let dog: Dog = Dog()
    dog.eat(food)
}
-- OC_project-Bridging-Header.h --
#import "Dog.h"
-- ViewController.m --
@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 依赖于Apple自动生成的‘工程名-Swift.h’文件
    Person *p = [[Person alloc] init];
    NSLog(@"%@", p);
    [p think];
    [p eat];
    [p drink:@"咖啡"];
    [p dogThink]; // 添加
    [p dogEat:@"狗粮"]; // 添加
}

@end

以上是基于OC项目嵌入Swift文件,接下来我们在Swift项目中嵌入OC文件

Swift项目中嵌入OC文件相对比较简单,新建一基于Swfift的项目,比如:Swift_project, 然后新建OC类,在新建的时候同样按照系统提示生成bridge文件。

如果Swift类要调用OC,只须在Swift_project-Bridging-Header.h中#import相对应的OC类即可。如果OC类要调用Swift, 只需#import "Swift_project-Swift.h"即可。

示例:

-- Person.h --
@interface Person : NSObject

- (void)think;
- (void)dogThink;

@end

-- Person.m --
#import "Person.h"
#import "Swift_project-Swift.h"

@implementation Person

- (void)think {
    NSLog(@"think");
}

- (void)dogThink {
    Dog *d = [[Dog alloc] init];
    [d think];
}

@end

-- Dog.swift --
import UIKit

@objc
class Dog: NSObject {
    @objc
    public func think() -> Void {
        print("dong think, but different with person")
    }
}

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

推荐阅读更多精彩内容

  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    X先生_未知数的X阅读 15,960评论 3 119
  • JSON包括三种写法 :「JSON对象」「JSON数组」特别注意:1)属性要用双引号引起来,不能用单引号2)JSO...
    从前慢pearl阅读 11,632评论 0 0
  • 书还是要读的,文化还是要有的。暂且不说读书为了安邦强国,哪怕只是为了听得懂话,也得多少读点。作家王小波说:...
    DearSunshine阅读 237评论 0 2
  • 钱是什么? 爸妈爱人把钱给你,钱是爱 客户伙伴与你成交,钱是信任 因你所为付钱给你,钱是认可 收钱意味着什么? 自...
    崔颖2013阅读 325评论 1 0