Swift与Objective-C的兼容能力允许你在同一个工程中同时使用两种语言。你可以用这种叫做“mix and match”的特性来开发基于混合语言的应用。使用Swfit的最新特性--“mix and match”,你可以实现应用的一部分功能,并无缝地并入已有的Objective-C的代码中。

Mix and Match 概述

Swift与Objective-C文件可以在一个工程中并存,不管这个工程原本是基于Objective-C还是Swift。你可以直接往现有工程中简单地添加另一种语言的文件。这种自然的工作流使得创建混合语言的应用或framework target,与用单独一种语言时一样简单。
 
编写混合语言的工作流程只有一点点区别,这取决于你是在写应用还是写框架。下面描述了用两种语言在一个target中导入模型的情况,后续章节会有更多细节。
 
在同一个App Target中进行代码导入

如果你在写混合语言的应用,可能需要用Swift代码访问Objective-C代码,或者反之。本章描述的流程适用于non-framework target。
 
将Objective-C导入Swift
要在同一个app target中导入Objective-C文件供Swift使用,你需要依赖Objective-C的桥接头文件(Objective-C bridging header)来暴露给 Swift。当你添加 Swift 文件到现有的Objective-C应用时,Xcode 会自动创建这些头文件,反之亦然。
如果你同意,Xcode 会在源文件创建的同时生成头文件,并用product的模块名加上 -Bridging-Header.h命名。关于 product 的模块名,详见 Naming Your Product Module
 
你应该编辑这个头文件来对Swift暴露出Objective-C代码。
 
在同一target中将Objective-C代码导入到Swift中
 
1.在Objective-C桥接头文件中,导入任何你想暴露给 Swift 的头文件,例如:
OBJECTIVE-C
#import "XYZCustomCell.h"
#import "XYZCustomView.h"
#import "XYZCustomViewController.h"
2.在Build Settings中,确保Objective-C桥接头文件的build setting是基于 Swfit 编译器,即Code Generation 含有头文件的路径。这个路径必须是头文件自身的路径,而不是它所在的目录。
 
这个路径应该是你工程的相对路径,类似 Info.plist 在 Build Settings 中指定的路径。在大多数情况下,你不需要修改这个设置。
 
在这个桥接头文件中列出的所有公开的Objective-C 头文件都会对 Swift 可见。之后当前 target 的所有 Swift 文件都可以使用这些头文件中的方法,不需要任何import语句。用 Swift 语法使用这些Objective-C代码,就像使用系统自带的类一样。
SWIFT
let myCell = XYZCustomCell()
myCell.subtitle = "A custom cell"
将 Swift 导入Objective-C
向Objective-C中导入Swift代码时,你依赖 Xcode 生成的头文件来向Objective-C暴露 Swift 代码。这个自动生成Objective-C头文件,声明了target 中所有 Swift 代码中定义的接口。可以把这个Objective-C头文件看作 Swift 代码的umbrella header。它以 product 模块名加 -Swift.h 来命名。关于 product 的模块名,详见 Naming Your Product Module
 
你不需要做任何事情来生成这个头文件,只需要将它导入到你的Objective-C代码来使用它。注意这个头文件中的 Swift 接口包含了它所使用到的所有 Objc 类型。如果你在 Swift 代码中使用你自己的Objective-C类型,确保先将对应的 Objc 头文件导入到你的 Swift 代码中,然后才将 Swift 自动生成的头文件导入到 Objc .m 源文件中来访问 Swift 代码。
 
在同一target中将Swift代码导入到Objective-C中 
 
在相同 target 的 Objc .m 源文件中,用下面的语法来导入Swift 代码:
OBJECTIVE-C
#import “ProductModuleName-Swift.h”

target 中任何 Swift 文件将会对 Objc .m 文件可见,包括这个 import 语句。关于在 Objc 代码中使用 Swift 代码,详见 Using Swift from Objective-C。

在同个Framework Target中导入代码

如果你在写一个混合语言的框架,可能会从 Swift 代码访问 Objc 代码,或者反之。
 
将 Objc 导入 Swift
要将一些 Objc 文件导入到同个框架 target 的 Swift 代码中去,你需要将这些文件导入到 Objc 的  umbrella header  来供框架使用。
 
在同一framework中将Objective-C代码导入到Swift中
 
确保将框架 target 的  Build Settings > Packaging > Defines Module  设置为  Yes 。然后在你的  umbrella header  头文件中导入你想暴露给 Swift 访问的 Objc 头文件,例如:
OBJECTIVE-C
#import <XYZ/XYZCustomCell.h>
#import <XYZ/XYZCustomView.h>
#import <XYZ/XYZCustomViewController.h>
Swift 将会看到所有你在  umbrella header  中公开暴露出来的头文件,框架 target 中的所有 Swift 文件都可以访问你 Objc 文件的内容,不需要任何 import 语句。
SWIFT
let myCell = XYZCustomCell()
myCell.subtitle = "A custom cell"
将 Swift 导入 Objc
要将一些 Swift 文件导入到同个框架的 target 的 Objc 代码去,你不需要导入任何东西到umbrella header文件,而是将 Xcode 为你的Swift代码自动生成的头文件导入到你的 Obj .m 源文件去,以便在 Objc 代码中访问 Swift 代码。
 
在同一framework中将Swift代码导入到Objective-C中
 
1.确保将框架target 的 Build Settings > Packaging  中的  Defines Module  设置为  Yes 。用下面的语法将 Swift 代码导入到同个框架 target 下的 Objc .m 源文件去。
OBJECTIVE-C
#import <ProductName/ProductModuleName-Swift.h>

这个 import 语句所包含的 Swift 文件都可以被同个框架 target 下的 Objc .m 源文件访问。关于在 Objc 代码中使用 Swift 代码,详见 Using Swift from Objective-C

导入外部 Framework

你可以导入外部框架,不管这个框架是纯 Objc,纯 Swift,还是混合语言的。import 外部框架的流程都是一样的,不管这个框架是用一种语言写的,还是包含两种语言。当你导入外部框架时,确保  Build Setting > Pakaging > Defines Module  设置为  Yes 。
 
用下面的语法将框架导入到不同 target 的 Swift 文件中:
SWIFT
import FrameworkName
用下面的语法将框架导入到不同 target 的 Objc .m 文件中:
OBJECTIVE-C
@import FrameworkName;

在Objective-C中使用 Swift

当你将 Swift 代码导入 Objc 文件之后,用普通的 Objc 语法使用 Swift 类。
OBJECTIVE-C
MySwiftClass *swiftObject = [[MySwiftClass alloc] init];
[swiftObject swiftMethod];
Swift 的类或协议必须用  @objc attribute  来标记,以便在 Objc 中可访问。这个 attribute 告诉编译器这个 Swift 代码可以从 Objc 代码中访问。如果你的 Swift 类是 Objc 类的子类,编译器会自动为你添加  @objc attribute 。详见 Swift Type Compatibility
 
你可以访问 Swift 类或协议中用  @objc attribute  标记过东西,只要它和 Objc 兼容。不包括一下这些 Swift 独有的特性:
Generics - 范型 
Tuples - 元组 
Enumerations defined in Swift - Swift 中定义的枚举 
Structures defined in Swift - Swift 中定义的结构体 
Top-level functions defined in Swift - Swift Swift 中定义的顶层函数 
Global variables defined in Swift - Swift 中定义的全局变量 
Typealiases defined in Swift - Swift 中定义的类型别名 
Swift-style variadics 
Nested types - 嵌套类型 
Curried functions - 柯里化后的函数 
 
例如带有范型类型作为参数,或者返回元组的方法不能在Objective-C中使用。
 
为了避免循环引用,不要将 Swift 代码导入到Objective-C头文件中。但是你可以在Objective-C头文件中前向声明( forward declare )一个 Swift 类来使用它,然而,注意不能在Objective-C中继承一个 Swift 类。
 
在Objective-C头文件中引用Swift类
 
这样前向声明 Swift 类:
OBJECTIVE-C
// MyObjcClass.h 

@class MySwiftClass; 

@interface MyObjcClass : NSObject
- (MySwiftClass *)returnSwiftObject;
/* ... */
@end
Product Module命名

Xcode 为 Swift 代码生成的头文件的名称,以及 Xcode 创建的 Objc 桥接头文件名称,都是从你的 product 模块名生成的。默认你的 product 模块名和 product 名一样。然而,如果你的 product 名有特殊字符(nonalphanumeric,非数字、字母的字符),例如点号,那么它们会被下划线( _ )替换之后作为你的 product 模块名。如果 product 名以数字开头,那么第一个数字会用下划线替换掉。
 
你可以给 product 模块名提供一个自定义的名称,Xcode 会用这个名称来命名桥接的和自动生成的头文件。你只需要在修改在  build setting  中的  Product Module Name  即可。
 
故障排除和提醒

•把 Swift 和 Objc 文件看作相同的代码集合,并注意命名冲突;
 
•如果你用框架,确保  Build Setting > Pakaging > Defines Module  设置为  Yes ;
 
•如果你使用 Objc 桥接头文件,确保在  Build Settings  中 Objc 桥接头文件的  build setting  是基于 Swfit 编译器,即  Code Generation  含有头文件的路径。这个路径必须是头文件自身的路径,而不是它所在的目录。
 
•Xcode 使用你的 product 模块名,而不是 target 名来命名 Objc 桥接头文件和为 Swift 自动生成的头文件。详见 Naming Your Product Module
 
•为了在 Objc 中可用, Swift 类必须是 Objc 类的子类,或者用  @objc  标记;
 
•当你将 Swift 导入到 Objc 中时,记住 Objc 不会将 Swift 独有的特性翻译成 Objc 对应的特性。详见列表 Using Swift from Objective-C;
 
•如果你在 Swift 代码中使用你自己的 Objc 类型,确保先将对应的 Objc 头文件导入到你的 Swift 代码中,然后才将 Swift 自动生成的头文件 import 到 Objc .m 源文件中来访问 Swift 代码。
 
 
本章由CocoaChina的翻译小组成员 haolloyin(github主页翻译,转载请注明出处和译者信息,拒绝商业之用。

http://www.cocoachina.com/newbie/basic/2014/0605/8688.html

https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html#//apple_ref/doc/uid/TP40014216-CH10-XID_85

[Swift A] - Using Swift with Cocoa and Objective-C--Mix and Match的更多相关文章

  1. swift.org - About Swift 官网关于notes

    About Swifthtml, body {overflow-x: initial !important;}html { font-size: 14px; } body { margin: 0px; ...

  2. iOS开发零基础--Swift篇:Swift中数据类型

    Swift类型的介绍 Swift中的数据类型也有:整型/浮点型/对象类型/结构体类型等等 先了解整型和浮点型 整型 有符号 Int8 : 有符号8位整型 Int16 : 有符号16位整型 Int32 ...

  3. 在同个工程中使用 Swift 和 Objective-C(Swift 2.0更新)-b

    本节包含内容: Mix and Match 概述(Mix and Match Overview) 在同个应用的 target 中导入(Importing Code from Within the Sa ...

  4. Swift互用性: 使用Objective-C特性编写Swift类(Swift 2.0版)-b

    本节包括内容: 继承Objective-C的类(Inheriting from Objective-C Classes) 采用协议(Adopting Protocols) 编写构造器和析构器(Writ ...

  5. Swift 学习Using Swift mix and match, network: 写rss读者

    有使用第三方库.因此,需要使用mix and match财产. 请指出错误,谢谢! rss 阅读器,非常easy的代码.仅仅是为了学习swift语言而写. 1、BaseViewController.s ...

  6. iOS Swift 模块练习/swift基础学习

    SWIFT项目练习     SWIFT项目练习2 iOS Swift基础知识代码 推荐:Swift学习使用知识代码软件 0.swift中的宏定义(使用方法代替宏) 一.视图  +控件 1.UIImag ...

  7. 对象存储 - Swift 原理 及 Swift+keystone+dashboard 架构搭建

    1. 原理介绍 Swift 架构.原理及功能: http://www.cnblogs.com/sammyliu/p/4955241.html 总结的很详细也很全面,受益匪浅,感谢分享. 2. keys ...

  8. 【Swift学习】Swift编程之旅---构造方法(十八)

    初始化是为了使用某个类.结构体或枚举类型的实例而进行的准备过程.这个过程包括为每个存储的属性设置一个初始值,然后执行新实例所需的任何其他设置或初始化.   初始化是通过定义构造器(Initialize ...

  9. Swift翻译之-Swift语法入门 Swift语法介绍

    目录[-] Hello world - Swift 简单赋值 控制流 函数与闭包 对象和类 枚举与结构 协议和扩展 泛型 2014.6.3日,苹果公布最新编程语言Swift,Swift是一种新的编程语 ...

随机推荐

  1. POJ 3904 JZYZOJ 1202 Sky Code 莫比乌斯反演 组合数

    http://poj.org/problem?id=3904   题意:给一些数,求在这些数中找出四个数互质的方案数.   莫比乌斯反演的式子有两种形式http://blog.csdn.net/out ...

  2. 【SDOI2017】树点染色【线段树+LCT】

    本来只是想练练LCT,没想到是个线段树 对于操作1:诶新的颜色?这不是access吗? 也就是说,我们用一棵splay来表示一种颜色 操作2直接在LCT上乱搞-- 不对啊,操作3要查子树 诶好像是静态 ...

  3. Android之View / SurfaceView / GLSurfaceView

    Android游戏当中主要的除了控制类外就是显示类View.SurfaceView是从View基类中派生出来的显示类.android游戏开发中常用的三种视图是:view.SurfaceView和GLS ...

  4. JAVA对数字证书的常用操作(转载)

    一:需要包含的包 import java.security. * ; import java.io. * ; import java.util. * ; import java.security. * ...

  5. URAL 1997 Those are not the droids you're looking for 二分图最大匹配

    Those are not the droids you're looking for 题目连接: http://acm.timus.ru/problem.aspx?space=1&num=1 ...

  6. BZOJ 2243: [SDOI2011]染色 树链剖分 倍增lca 线段树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...

  7. ExtJS表格——行号、复选框、选择模型

    本篇的内容是为表格添加行号,和复选框,最后谈一下Ext的选择模型.内容比较简单,就直接上代码了.一. 设置行号   行号的设置主要问题在于删除某一行后需要重新计算行号  Ext.onReady(fun ...

  8. JSP中Out和Request对象详解

    内置表示不需要new便可直接使用. 一.基础知识 1.缓冲区:IO最原始是一个一个字节的读取,这就像吃米饭的时候一粒一粒的吃,很没有效率,这时候就有了碗,一碗一碗的吃,岂不痛快. 2.Get提交不能超 ...

  9. PHP 函数之 call_user_func &amp; call_user_func_array

    call_user_func_array (callable $callback, array $param_arr) 參数1: 调用一个回调函数, 參数2: 数组參数是回调函数的參数. call_u ...

  10. .Net4.0并行库介绍——Cancellation Framework

    在.net 4.0中,引入了一个新的类CancellationToken,这个类基本上集成了我们各种常用的取消方式,在并发任务中非常有用. 同步模式下的取消: 一种比较常见的需要支持取消功能的的是一些 ...