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

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbmV4dGo=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

Swift系列文章由CocoaChina翻译小组翻译自苹果的官方文档:Using
Swift with Cocoa and Objective-C--Swift and Objective-C in the Same Project
。本篇译者:haolloyin(github主页),敬请勘误。

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

 
Mix and Match 概述

Swift与Objective-C文件能够在一个project中并存,无论这个project原本是基于Objective-C还是Swift。

你能够直接往现有project中简单地加入还有一种语言的文件。这样的自然的工作流使得创建混合语言的应用或framework target,与用单独一种语言时一样简单。

 
编写混合语言的工作流程仅仅有一点点差别。这取决于你是在写应用还是写框架。以下描写叙述了用两种语言在一个target中导入模型的情况,兴许章节会有很多其它细节。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbmV4dGo=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

在同一个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代码。
 
To import Objective-C code into Swift from the same target
 
1.在Objective-C桥接头文件里,导入不论什么你想暴露给 Swift 的头文件。比如:
OBJECTIVE-C
  1. #import "XYZCustomCell.h"
  2. #import "XYZCustomView.h"
  3. #import "XYZCustomViewController.h"
2.在Build Settings中,确保Objective-C桥接头文件的build setting是基于 Swfit 编译器,即Code Generation 含有头文件的路径。

这个路径必须是头文件自身的路径。而不是它所在的文件夹。

 
这个路径应该是你project的相对路径,类似 Info.plist 在 Build Settings 中指定的路径。在大多数情况下,你不须要改动这个设置。
 
在这个桥接头文件里列出的全部公开的Objective-C 头文件都会对 Swift 可见。

之后当前 target 的全部 Swift 文件都能够使用这些头文件里的方法,不须要不论什么import语句。

用 Swift 语法使用这些Objective-C代码,就像使用系统自带的类一样。

SWIFT
  1. let myCell = XYZCustomCell()
  2. 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 代码。

 
To import Swift code into Objective-C from the same target
 
在同样 target 的 Objc .m 源文件里。用以下的语法来导入Swift 代码:
OBJECTIVE-C
  1. #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  来供框架使用。
 
To import Objective-C code into Swift from the same framework
 
确保将框架 target 的  Build Settings > Packaging > Defines Module  设置为  Yes 。然后在你的  umbrella header  头文件里导入你想暴露给 Swift 訪问的 Objc 头文件,比如:
OBJECTIVE-C
  1. #import <XYZ/XYZCustomCell.h>
  2. #import <XYZ/XYZCustomView.h>
  3. #import <XYZ/XYZCustomViewController.h>
 
Swift 将会看到全部你在  umbrella header  中公开暴露出来的头文件,框架 target 中的全部 Swift 文件都能够訪问你 Objc 文件的内容,不须要不论什么 import 语句。

SWIFT
  1. let myCell = XYZCustomCell()
  2. myCell.subtitle = "A custom cell"
 
 
将 Swift 导入 Objc
要将一些 Swift 文件导入到同个框架的 target 的 Objc 代码去,你不须要导入不论什么东西到umbrella header文件,而是将 Xcode 为你的Swift代码自己主动生成的头文件导入到你的 Obj .m 源文件去。以便在 Objc 代码中訪问 Swift 代码。
 
To import Swift code into Objective-C from the same framework
 
1.确保将框架target 的 Build Settings > Packaging  中的  Defines Module  设置为  Yes 。用以下的语法将 Swift 代码导入到同个框架 target 下的 Objc .m 源文件去。
OBJECTIVE-C
  1. #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
  1. import FrameworkName
 
用以下的语法将框架导入到不同 target 的 Objc .m 文件里:
OBJECTIVE-C
  1. @import FrameworkName;
 
在Objective-C中使用 Swift

当你将 Swift 代码导入 Objc 文件之后,用普通的 Objc 语法使用 Swift 类。
OBJECTIVE-C
  1. MySwiftClass *swiftObject = [[MySwiftClass alloc] init];
  2. [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 类。

 
To reference a Swift class in an Objective-C header file
 
这样前向声明 Swift 类:
OBJECTIVE-C
  1. // MyObjcClass.h
  2. @class MySwiftClass;
  3. @interface MyObjcClass : NSObject
  4. - (MySwiftClass *)returnSwiftObject;
  5. /* ... */
  6. @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 代码。

Using Swift with Cocoa and Objective-C--在同个project中使用Swift和在同个project中的更多相关文章

  1. iOS开发——技术精华Swift篇&Swift 2.0和Objective-C2.0混编之第三方框架的使用

    swift 语言是苹果公司在2014年的WWDC大会上发布的全新的编程语言.Swift语言继承了C语言以及Objective-C的特性,且克服了C语言的兼容性问题.Swift语言采用安全编程模式,且引 ...

  2. Using Swift with Cocoa and Objective-C(Swift 2.0版):开始--基础设置-备

    这是一个正在研发的API或技术的概要文件,苹果公司提供这些信息主要是为了帮助你通过苹果产品使用这些技术或者编程接口而做好计划,该信息有可能会在未来发生改变,本文当中提到的软件应该以最终发布的操作系统测 ...

  3. Using Swift with Cocoa and Objective-C下载

    <Using Swift with Cocoa and Objective-C Building App > 下载地址 http://download.csdn.net/detail/sw ...

  4. [Swift A] - Using Swift with Cocoa and Objective-C--Mix and Match

    Swift与Objective-C的兼容能力允许你在同一个工程中同时使用两种语言.你可以用这种叫做“mix and match”的特性来开发基于混合语言的应用.使用Swfit的最新特性--“mix a ...

  5. 如何在C语言中调用Swift函数

    在Apple官方的<Using Swift with Cocoa and Objectgive-C>一书中详细地介绍了如何在Objective-C中使用Swift的类以及如何在Swift中 ...

  6. 如何在 iOS 8 中使用 Swift 实现本地通知(上)

    当你的应用在后台运行时,可以简单地使用本地通知把信息呈现给用户.它可以允许你显示 提醒.播放提示音和数字角标(badge).本地通知可以被以下的事件触发:计划好的时间点或者用户进入和离开某个地理区域. ...

  7. 使用Pods中使用Swift和Objective-C混编-编译不通过的原因

    iOS开发#使用Pods中使用Swift和Objective-C混编-编译不通过的原因-ld: symbol(s) not found for architecture arm64 问题基本描述 在P ...

  8. OC项目中使用Swift

    1.在OC工程中新建 Swift 文件,会提示的是否创建一个桥接文件,创建不创建都无所谓,这个桥接文件主要是用来包含OC头文件的,主要用于Swift中使用OC         2.在Person.sw ...

  9. 在oc代码中使用swift第三方框架

    swift现在使用越来越多了,一些主流的框架或者效果比较好的demo都陆陆续续使用swift写了.所以,要学会如何在oc的项目中调用swift. 这里主要借助一个桥梁文件,这个桥梁文件一般在你导入sw ...

随机推荐

  1. love2d教程33--window模块

    --love的window模块比较简单,直接贴代码了function love.load() io.stdout:setvbuf("no") -- 设置io为无缓存模式 --获取显 ...

  2. IDEA2017 导入 SVN上的 Myeclipse或Eclipse 项目

    从SVN上检出项目,不用打开. 关闭IDEA后选择 import project,导入后按F4 (改成eclipse按键模式后 按ctrl alt shift F4)进入 project struct ...

  3. Unity5.1 新的网络引擎UNET(四) UNET Remote Actions

    孙广东   2015.7.12 网络系统 具有网络中执行操作actions 的方法.这些类型的actions 有时是调用远程过程调用(Remote Procedure Calls). 在网络系统中有两 ...

  4. [转]JVM内存溢出的几种方式比较

    转载自:https://github.com/pzxwhc/MineKnowContainer/issues/25 包括: 1. 栈溢出(StackOverflowError) 2. 堆溢出(OutO ...

  5. 亿级日PV的魅族云同步的核心协议与架构实践

    声明:本文根据msup和魅族联合举办的<第三期魅族技术开放日-架构设计与优化>录音整理原创首发,转载或节选内容前需获授权. 嘉宾:沈辉煌,魅族高级架构师,魅族云同步负责人.2010年加入魅 ...

  6. 第二百三十六节,Bootstrap辅组类和响应式工具

    Bootstrap辅组类和响应式工具 学习要点: 1.辅组类 2.响应式工具 本节课我们主要学习一下 Bootstrap 的辅组类和响应式工具,辅助类提供了一组类来辅 组页面设计,而响应式工具则利用媒 ...

  7. List、Map、Set三个接口存储元素时各有什么特点?

    List.Map.Set三个接口存储元素时各有什么特点? 解答: 1)List是有序的Collection,使用此接口能够精确的控制每个元素插入的位置.用户能够使用索引(元素在List中的位置,类似于 ...

  8. 【BZOJ】3391: [Usaco2004 Dec]Tree Cutting网络破坏(dfs)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3391 显然判断每个点只需要判断子树是否小于等于n/2即可 那么我们虚拟一个根,然后计算每个子树的si ...

  9. js Date操作

    new Date(new Date().getTime() - 24 * 24 * 60 * 60 * 1000)类似C#中的AddDays,返回一个月前的时间  //时间格式化方法        v ...

  10. 蓝桥杯 第三届C/C++预赛真题(5) 转方阵(C基本功)

    对一个方阵转置,就是把原来的行号变列号,原来的列号变行号 例如,如下的方阵: 1 2 3 4 5 6 7 8 9 10 11 1213 14 15 16 转置后变为: 1 5 9 13 2 6 10 ...