• Using Swift with Cocoa and Objective-C--在同个project中使用Swift和在同个project中


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



    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中导入模型的情况,兴许章节会有很多其它细节。

    在同一个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.   
    2. #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.   
    2. import FrameworkName 
     
    用以下的语法将框架导入到不同 target 的 Objc .m 文件里:
    OBJECTIVE-C
    1.   
    2. @import FrameworkName; 
     
    在Objective-C中使用 Swift

    当你将 Swift 代码导入 Objc 文件之后,用普通的 Objc 语法使用 Swift 类。
    OBJECTIVE-C
    1.   
    2. MySwiftClass *swiftObject = [[MySwiftClass alloc] init]; 
    3. [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.   
    3. @class MySwiftClass; 
    4.   
    5. @interface MyObjcClass : NSObject 
    6. - (MySwiftClass *)returnSwiftObject; 
    7. /* ... */ 
    8. @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 代码。

  • 相关阅读:
    Java类、实例初始化的顺序
    Java中堆栈的区别
    int与Integer的区别(基本类型与复杂类型的对比)转
    JS中函数执行顺序的问题?
    springMVC --@RequestParam注解(后台控制器获取参数)
    如何安装request库
    流程图
    认识broken pipe
    postman动态使用url
    自定义一个List排序规则,然后对另一个List按照该规则排序
  • 原文地址:https://www.cnblogs.com/jzssuanfa/p/6719265.html
Copyright © 2020-2023  润新知