Swift项目兼容ObjectiveC问题汇总
- 格式:docx
- 大小:1.35 MB
- 文档页数:10
Swift和C语言混合编程教程这篇文章主要介绍了Swift和C语言混合编程教程,介绍基本数据类型对比、指针、常量等内容,需要的朋友可以参考下作为一种可与Objective-C 相互调用的语言,Swift 也具有一些与C 语言的类型和特性,如果你的代码有需要,Swift 也提供了和常见的C 代码结构混合编程的编程方式。
基本数据类型Swift 提供了一些和C 语言的基本类型如char,int,float,double等价的Swift 基本数据类型。
然而,这些Swift 的核心基本类型之间并不能隐式的相互转换,如Int。
因此,只有你的代码明确要求它们时再使用这些类型,而Int 可以在任何你想使用它的时候使用。
C 类型Swift 类型boolCBoolchar, signed charCCharunsigned charCUnsignedCharshortCShortunsigned short CUnsignedShortintCIntunsigned int CUnsignedIntlongCLongunsigned long CUnsignedLonglong long CLongLongunsigned long long CUnsignedLongLongwchar_tCWideCharchar16_tCChar16char32_tCChar32floatCFloatdoubleCDouble枚举Swift 引进了用宏NS_ENUM来标记的任何C 风格的枚举类型。
这意味着无论枚举值是在系统框架还是在自定义的代码中定义的,当他们导入到Swift 时,他们的前缀名称将被截断。
例如,看这个Objective-C 枚举:复制代码代码如下://Objective-Ctypedef NS_ENUM(NSInteger, UITableViewCellStyle) {UITableViewCellStyleDefault,UITableViewCellStyleValue1,UITableViewCellStyleValue2,UITableViewCellStyleSubtitle};在Swift 中这样来实现:复制代码代码如下://Swiftenum UITableViewCellStyle: Int {case Defaultcase Value1case Value2case Subtitle}当您需要指向一个枚举值时,使用以点(.)开头的枚举名称:复制代码代码如下://Swiftlet cellStyle: UITableViewCellStyle = .DefaultSwift 也引进了标有NS_OPTIONS宏选项。
简析Swift和C的交互C中有指针,而Swift中没有,同时基本类型还有很多不同。
所以混编难免需要在两种语言的不同类型之间进行转换。
牢记一个万能函数reinterpretCast(T) -> U,只要T,U sizeof运算相等就可以直接转其中@asmname的两个用法源于我的猜测验证,用到了Xcode, lldb, nm, llvm ir 等工具或格式。
其中namemangling部分源自WWDC。
相关的分析主要基于我dump出的Swift 标准库声明代码,位于我的Github andelf/Defines-Swift。
之前好像简单说过Swift和Objective-C 的交互问题。
其实我们也可以用Swift 调用纯C 代码或者基于C 的第三方库。
(这里不会也永远不会考虑C++ 的情况,因为不支持,不过可以用C 写wrapper,这个没有任何问题。
)Swift 官方文档中,以及那本已经被迅速翻译为中文的ibooks 书中,都提到了Sw ift调用Objective-C 和C 是有很好支持的。
不过没有细节。
本内容包括Swift 调用C 和相应的C调用Swift,项目混编。
这里主要面向MacOSX 应用。
iOS 或许可以适用。
先复习下区别。
第一部分预备知识语言区别说到底就是C 少了很多东西。
但是多了个指针。
对于C来说,最头疼的莫过于指针,而Swift 是一门没有指针的语言。
是不是要吐血?相对来说指针不但代表者指针操作传参,还有指针运算等等。
第二部分调用C这里主要讨论函数的调用。
对于结构、枚举、类的兼容性暂时没尝试。
C标准库好消息是,对于标准库中的C 函数,根本不需要考虑太多导入头文件神马的。
比如strlen、putchar、vprintf。
当然vprintf 需要多说几句,后面说。
请直接import Darwin 模块。
这些标准库函数表示为Darwin.C.HEADER.name。
实际上由于Swift模块结构是平坦的,他们均位于Darwin 中,所以基本上是直接用的。
Swift中调用Aspects之将闭包封装成AnyObject详解在iOS应用开发中,Aop神器 Aspects 在objective-c编程语言中使用非常简单。
但随着swift的广发使用,其在swift语言中能否正常使用呢?苹果公司这么大力发展swift语言,Aspects在swift肯定是能正常使用的,本文小编就将和大家一起来聊聊Aspects在swift中的使用。
在swift中,Aspects虽然能正常使用,但是也有些限制,aspects利用objc runtime 的方法来实现的,所以在swift下,只能观察swift下的NSObject(带有@objc关键字的对象)。
这里还是建议新建对象的时候直接继承NSObject。
这样就不用自己标注@objc关键字。
在 Swift 类型文件中,我们可以将需要暴露给 Objective-C编程语言使用的任何地方(包括类,属性和方法等) 的声明前面加上 @objc 修饰符。
但需要注意的是,这个步骤只需要对那些不是继承自 NSObject 的类型进行,如果你用 Swift 写的 class 是继承自NSObject 的话,Swift 会默认自动为所有的非 private 的类和成员加上 @objc下面我们继续来看看Aspects的一个方法- (id<AspectToken>)aspect_hookSelector:(SEL)selector<br />withOptions:(AspectOptions)options<br /> usingBlock:(id)block<br /> error:(NSError**)error;为了对比,这里放一下UIView的一个方法+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void(^)(void))animations注意block的类型,UIView的方法中已经直接声明好参数和返回值。
本文由我司收集整编,推荐下载,如有疑问,请与我司联系使用Swift 实现Objective C 库中的方法使用Swift 实现Objective C 库中的方法[英]Implementing Methods from ObjectiveC Library with Swift I am trying to implement the following method in swift:我试图在swift 中实现以下方法:From the class FLIROneSDKImageReceiverDelegate, which is subclassed inside myViewController class as so:从FLIROneSDKImageReceiverDelegate 类中,它是我的ViewController 类中的子类,如下所示:class ViewController: UIViewController, FLIROneSDKImageReceiverDelegate, FLIROneSDKStreamManagerDelegate, FLIROneSDKImageEditorDelegate{ Note that I have already created a bridging header etc.请注意,我已经创建了一个桥接头等。
In the FLIROneSDKImageReceiverDelegate header file:在FLIROneSDKImageReceiverDelegate 头文件中:- (void) FLIROneSDKDelegateManager:(FLIROneSDKDelegateManager *)delegateManager didReceiveBlendedMSXRGBA8888Image:(NSData *)msxImage imageSize:(CGSize)size; Am I wrong in thinking that this is the correct way to implement this function?我认为这是实现此功能的正确方法我错了吗?func FLIROneSDKDelegateManagerdidReceiveBlendedMSXRGBA8888ImageimageSize(dele gateManager: FLIROneSDKDelegateManager!, msxImage: NSData, size: CGSize){ Note that FLIROneSDKDelegateManager is a class.请注意,FLIROneSDKDelegateManager 是一个类。
WWDC 2014上苹果再次惊世骇俗的推出了新的编程语言SWIFT( 雨燕), 这个消息会前没有半点风声的走漏。
消息发布当时,会场一片惊呼,相信全球看直播的码农们当时也感觉脑袋被敲了一记闷棍吧(至少我当时是这样的,连喊三声:“卧槽,妈蛋” )。
于是熬夜学习了SWIFT大法,越看越想高呼”SWIFT大法好!“个人愚见:swift语言替代objective-c只是时间问题(这个时间不会太长)---扬起大脸迎接喷子们空说无凭,程序员,最讲究的就是实事求是和客观,下面就开始对比两种语言。
首先要强调的是,swift绝对不是解释性语言,更不是脚本语言,它和objective-c,c++一样,编译器最终会把它翻译成C语言,也就是说编译器最终面对的其实都是C语言代码(这是千真万确,不容置疑的!!!所以不要看它长的想脚本语言,其实它是比java, c#要高效的多的c语言!!!),但是swift的强大之处在于它站在所有语言的肩膀上,吸取所有语言的精华。
这个系列我们先谈谈几个最基本的语法变化《一》swift终于放弃了objective-c那幺蛾子般的[ obj method:x1 with:x2] 的语法,终于跟随了大流,变成了obj.method( )的顺眼模式。
虽然对于objective-c 的程序员来说,这些[ ]看上去特显酷,你们知道就是这个中括弧吓跑了多少c++, java , c#的程序员嘛?所以说这个小小的变化,可以让苹果的开发更平易近人,对有其他开发语言基础的人来说更友好。
但苹果不会这么自甘平庸,我们知道objective-c里方法的调用有种语法是其他主流语言没有的,那就是标签。
我们在使用java, c++, c, c#等语言时,如果使用rect.set( 10, 20, 100, 500 ), 虽然在写set方法的时候,IDE有提示四个形参的含义,但写完后,鬼知道这句代码中10,20,100,500是啥意思?(我是举了个简单的例子,不要因此怀疑我的智商!)。
Objective-C、C++和swift的运⾏效率⽐较⾃⼰做iOS开发,以后慢慢都要转swift,前段时间看到⽹上的⼀个帖⼦,说swift的运⾏效率奇低,觉得⾃⼰有必要验证⼀下。
我⽤了⼀个最简单的加法运算,从0加到10000000,看三种语⾔的时耗。
swift 2.2:import Foundationlet start = CFAbsoluteTimeGetCurrent()var sum = 0for i in 0...10000000{sum += i;}print("swift")print(sum)print(String(CFAbsoluteTimeGetCurrent() - start) + "s")运⾏结果:Objective-C 2.0:1#import <Foundation/Foundation.h>23int main(int argc, const char * argv[]) {4 @autoreleasepool {5 NSInteger sum = 0;6 CFTimeInterval start = CFAbsoluteTimeGetCurrent();7for (int i = 0; i <= 10000000; i++) {8 sum += i;9 }10 CFTimeInterval end = CFAbsoluteTimeGetCurrent();11 CFTimeInterval dur = end - start;12 printf("Objective-C sum=%ld\n",sum);13 printf("dur:%f s\n",dur);1415 }16return0;17 }运⾏结果:C++ 11:1int main(int argc, const char * argv[]) {2 chrono::system_clock::time_point startTime = chrono::system_clock::now();3long sum = 0;4for (int i = 0; i < 10000000; i++) {5 sum += i;6 }7 chrono::system_clock::time_point endTime = chrono::system_clock::now();8 cout << "C++ sum: " << sum << endl;9 cout << "duration: " <<(endTime - startTime).count()*1.0/CLOCKS_PER_SEC << "s" << endl;10return0;11 }运⾏结果:运⾏结果可以发现:C++的效率⽐Objective-C 和 swift 的效率要⾼,C++ 只⽐ Objective-C 稍⾼⼀点,且⼆者的精度都⽐swift的低,要那么⾼精度有什么⽤,不知道苹果的⽤意。
iOS:swift:可选类型import UIKit/*:可选类型* 可选类型表⽰变量可以有值, 也可以没有值* C 和 Objective-C 中并没有可选类型这个概念* Swift中只有可选类型才可以赋值为nil* 如果你声明⼀个可选常量或者变量但是没有赋值,它们会⾃动被设置为nil* 格式: Optional<类型> 或在类型后⾯加上?号可选类型的取值是⼀个枚举* None 没有值* Some 有值* 由于可选类型在Swift中随处可见, 所以系统做了⼀个语法糖, 在类型后⾯加上?注意:* nil不能⽤于⾮可选的常量和变量。
如果你的代码中有常量或者变量需要处理值缺失的情况,请把它们声明成对应的可选类型。
* Swift 的nil和 Objective-C 中的nil并不⼀样。
在 Objective-C 中,nil是⼀个指向不存在对象的指针, 所以Objective-C只有对象类型才能被设置为nil(基本类型不⾏)。
在 Swift 中,nil不是指针——它是⼀个确定的值,⽤来表⽰值缺失。
任何类型的可选状*/var number: Optional<Int>number = 10number = nilvar number1: Intnumber1 = 10//number1 = nil// 推荐var number2: Double?number2 = 20.1//number2 = nil// Swift中可选类型的值不能当做普通类型的值来使⽤// 如果想使⽤可选类型的值必须进⾏解包操作// 只需要在变量/常量后⾯加上! 就可以解包// 解包代表着告诉系统, 该变量/常量中⼀定有值var number3: Doublenumber3 = 3.14print(number2)print(number2!)print(number3)let sum = number2! + number3/*强制解析(forced unwrapping)* init? 构造函数, ?表⽰不⼀定能够实例化出对象* !表⽰告诉编译器⼀定有值, 编译能够通过, 如果运⾏时没有值就会直接崩溃* 提⽰: ? 和 ! 是所有刚刚接触Swift的OC程序员最最蛋疼的问题, 前期开发要注意多看⽂档和利⽤编译器提⽰解决(option + click)注意* 在Swift开发中, 尽量不要使⽤强制解包, 不安全*/let url = NSURL(string: "")print(url)//print(url!)let url1 = NSURL(string: "/图⽚/abc.png")print(url1)/*:可选绑定(optional binding)* 不需要考虑url是否有值, 能进⼊{}⼀定有值* 不仅可以⽤来判断可选类型中是否有值,同时可以将可选类型中的值赋给⼀个常量或者变量* 可选绑定可以⽤在if和while语句中提⽰:* 在实际开发中,使⽤频率很⾼注意:* 可选绑定中的变量/常量只能在if后⾯的{}中使⽤*/if let temp = url {print(temp)}let value1: Int? = 10let value2: Int? = 20let value3: Int? = 30let value4: Int? = 40if let temp1 = value1 {if let temp2 = value2 {if let temp3 = value3 {if let temp4 = value4 {let sum = temp1 + temp2 + temp3 + temp4}}}}/*:guard* guard语句是在Swift 2.0中引进的,它是⽤途是在未满⾜某个条件时,提供⼀个退出的路径* 格式: guard 表达式 else{}注意:* guard中的变量/常量可以在guard后⾯使⽤* guard⼀般⽤于避免使⽤强制拆包, 优化代码结构*/func test(){let value1: Int? = 10let value2: Int? = 20let value3: Int? = 30let value4: Int? = 40guard let temp1 = value1 else{return}guard let temp2 = value2 else{return}guard let temp3 = value3 else{return}guard let temp4 = value4 else{return}let sum = temp1 + temp2 + temp3 + temp4print(sum)}test()/*隐式解析可选类型(implicitly unwrapped optionals)* 有时候在程序架构中,第⼀次被赋值之后,可以确定⼀个可选类型_总会_有值。
swift 引用oc的代理方法Yes, it is definitely possible to reference an Objective-C protocol from Swift. 在Swift中引用Objective-C的代理方法是完全可行的。
Objective-C protocols can be referenced in Swift by using the objc attribute in the protocol declaration, which allows the protocol to be exposed to the Objective-C runtime. 这可以通过在协议声明中使用objc 属性来实现,这允许该协议在Objective-C运行时中暴露出来。
By using this attribute, you can ensure that the protocol is accessible from both Swift and Objective-C code. 通过使用这个属性,你可以确保这个协议可以从Swift和Objective-C代码中访问。
In addition, you can use objc protocol to declare the protocol in Swift, which will make it available to Objective-C. 另外,你可以使用objc协议在Swift中声明协议,这样就可以使它在Objective-C中可用。
When referencing an Objective-C protocol from Swift, it's important to remember that the method signatures in the protocol must be marked with the objc attribute. 在Swift中引用Objective-C的协议时,要记住协议中的方法签名必须用objc属性标记。
本文由我司收集整编,推荐下载,如有疑问,请与我司联系使用Swift 向keychain 添加项。
2014/06/09 13274 I’m trying to add an item to the iOS keychain using Swift but can’t figure out how to type cast properly. From WWDC 2013 session 709, given the following Objective-C code:我正在尝试使用Swift 向iOS keychain 添加一个项目,但是我不知道如何正确地键入cast。
从WWDC 2013 年第709 届开始,给定以下Objective-C 代码:NSData *secret = [@”top secret”dataWithEncoding:NSUTF8StringEncoding];NSDictionary *query = @{ (id)kSecClass: (id)kSecClassGenericPassword, (id)kSecAttrService: @”myservice”, (id)kSecAttrAccount: @”account name here”,(id)kSecValueData: secret,OSStatus = SecItemAdd((CFDictionaryRef)query, NULL); Attempting to do it in Swift as follows:尝试以以下方式迅速完成:var secret: NSData = “Top Secret”.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)var query: NSDictionary = [ kSecClass: kSecClassGenericPassword, kSecAttrService: “MyService”,kSecAttrAccount: “Some account”,kSecValueData: secret yields the error “Cannot convert the expression’s type‘Dictionary’ to ‘DictionaryLiteralConvertible’.产生错误“无法将表达式的类型’Dictionary’转换为’DictionaryLiteralConvertible’”。
在Objective-C(以下简称OC)中引用Swift framework(以下简称框架)是一项具有丰富挑战性和技术含量的任务。
本文将从深度和广度两个方面对这一主题进行全面评估,并为您撰写一篇有价值的文章。
一、框架的引入和使用1. 让我们来探讨在OC项目中引入Swift框架的基本步骤。
在Xcode中新建一个OC项目,并添加Swift框架的过程中,需要注意的一些关键点和细节。
2. 我们将讨论在OC项目中如何正确地使用引入的Swift框架。
这涉及到框架中Swift与OC之间的交互,以及在OC代码中调用Swift框架的一些注意事项和技巧。
3. 我们将对引入和使用Swift框架的整个过程进行总结和回顾,阐述其中的一些难点、解决方案以及值得注意的问题。
二、框架的内部实现1. 我们将深入了解Swift框架的内部实现原理。
这涉及到Swift代码在编译后是如何转换为OC可调用的形式,以及框架中可能存在的一些特殊机制和技术细节。
2. 我们将解析框架中一些常见的Swift特性在OC项目中的使用方式。
在OC中如何调用Swift中的闭包、协议、枚举等特性,以及如何正确地处理类型转换和错误处理等情况。
3. 我们将对框架的内部实现进行综合讨论和分析,探讨其中的一些深层次问题和技术瓶颈,为读者提供更加全面深入的理解和思考。
三、个人观点和理解在我看来,OC中引用Swift框架是一项技术上非常具有挑战性和创新性的工作。
它不仅需要我们熟练掌握OC和Swift两种编程语言,还需要深入理解它们之间的交互机制和原理。
它也为我们提供了一个更加灵活和强大的跨语言开发评台。
在未来的发展中,我相信这种跨语言框架的引入和使用会变得越来越普遍,也会为我们带来更多的技术挑战和机遇。
总结而言,在OC中引用Swift框架是一项具有一定技术难度和挑战性的任务。
但只要我们深入理解其内部实现原理和技术细节,并结合实际项目需求做好相应的调整和优化,就可以顺利地完成这项工作。
Swift项目兼容ObjectiveC问题汇总一、解决问题Swift项目需要使用封装好的Objective-c组件、第三方类库,苹果提供的解决方案能够处理日常大部分需求,但还不能称之为完美,混编过程中会遇到很多问题。
本文将Swift兼容Objective-c的问题汇总,以帮助大家更好的使用Swift,内容列表如下:1. Swift调用Objective-c代码2. Objective-c调用Swift代码3. Swift兼容Xib/Storyboard4. Objective-c巧妙调用不兼容的Swift方法5. 多Target编译错误解决6. 第三方类库支持二、基础混合编程Swift与Objective-c的代码相互调用,并不像Objective-c与C/C++那样方便,需要做一些额外的配置工作。
无论是Swift调用Objective-c还是Objective-c调用Swift,Xcode在处理上都需要两个步骤:2.1 Swift调用Objective-c代码Xcode对于Swift调用Objective-c代码,除宏定义外,其它支持相对完善。
2.1.1 使用Objetvie-c的第一步告诉Xcode、哪些Objective-c类要使用,新建.h头文件,文件名可以任意取,建议采用“项目名-Bridging-Header.h”命令格式。
TipsSwift之IOS项目,在Xcode6创建类文件,默认会自动选择OS X标签下的文件,这时一定要选择iOS标签下的文件,否则会出现语法智能提示不起作用,严重时会导致打包出错。
2.1.2 第二步,Target配置,使创建的头文件生效设置Objective-C Bridging Header时,路径要配置正确,例如:创建的名为“ILSwift-Bridging-Header.h”文件,存于ILSwift项目文件夹的根目录下,写法如下:ILSwift/ILSwift-Bridging-Header.h当然,在新项目中,直接创建一个Objective-c类,Xcode会提示:直接选择Yes即可,如果不小心点了其它按钮,可以按照上面的步骤一步一步添加。
2.2 Objective-c调用Swift代码2.2.1 Objective-c调用Swift代码两个步骤第一步告诉Xcode哪些类需要使用(继承自NSObject的类自动处理,不需要此步骤),通过关键字@objc(className)来标记import UIKit@objc(ILWriteBySwift)class ILWriteBySwift {var name: String!class func newInstance() -> ILWriteBySwift {return ILWriteBySwift()}}第二步引入头文件,Xcode头文件的命名规则为$(SWIFT_MODULE_NAME)-Swift.h示例如下:#import"ILSwift-Swift.h"Tips不清楚SWIFT_MODULE_NAME可通过以下步骤查看2.2.2找不到$(SWIFT_MODULE_NAME)-Swift.h1.遇到此问题可按以下步骤做常规性检查确定导入SWIFT_MODULE_NAME)-Swift.h头文件的文件名正确SWIFT_MODULE_NAME)-Swift.h在clean后没有重新构建,执行Xcode->Product->Build2.头文件循环在混合编程的项目中,由于两种语言的同时使用,经常会出现以下需求:在Swift项目中需要使用Objectvie-c写的A类,而A类又会用到Swift的一些功能,头文件的循环,导致编译器不能正确构建$(SWIFT_MODULE_NAME)-Swift.h,遇到此问题时,在.h文件做如下处理//删除以下头文件//#import "ILSwift-Swift.h"//通过代码导入类@class ILSwiftBean;在Objevtive-c的.m文件最上面,添加#import"ILSwift-Swift.h"出现Use of undecalared identifier错误或者找不到方法,如下:引起的原因有以下几种可能:使用的Swift类不是继承自NSObject,加入关键字即可SWIFT_MODULE_NAME)-Swift.h没有实时更新,Xcode->Product->Build此Swift文件中使用了Objective-c不支持的类型或者语法,如private出现部分方法找不到的问题,Xcode无智能提示:此方法使用了Objective-c不支持的类型或者语法苹果官方给出的不支持转换的类型GenericsTuplesEnumerations defined in SwiftStructures defined in SwiftTop-level functions defined in SwiftGlobal variables defined in SwiftTypealiases defined in SwiftSwift-style variadicsNested typesCurried functions三、Xib/StoryBoard支持Swift项目在使用Xib/StoryBoard时,会遇到两种不同的问题Xib:不加载视图内容Storyboard:找不到类文件3.1 Xib不加载视图内容在创建UIViewController时,默认选中Xib文件,在Xib与类文件名一致时,可通过以下代码实例化:let controller = ILViewController()运行,界面上空无一物,Xib没有被加载。
解决办法,在类的前面加上@objc(类名),例如:import UIKit@objc(ILViewController)class ILViewController: UIViewController {}Tips:StoryBoard中创建的UIViewController,不需要@objc(类名)也能够保持兼容3.2 Storyboard找不到类文件Swift语言引入了Module概念,在通过关键字@objc(类名)做转换的时候,由于Storboard没有及时更新Module属性,会导致如下两种类型错误:3.2.1 用@objc(类名)标记的Swift类或者Objective-c类可能出现错误:2015-06-02 11:27:42.626 ILSwift[2431:379047] Unknown class _TtC7ILSwift33ILNotFindSwiftTagByObjcController in Interface Builder file.解决办法,按下图,选中Module中的空白,直接回车3.2.2 无@objc(类名)标记的Swift类2015-06-0211:36:29.788 ILSwift[2719:417490] Unknown class ILNotF indSwiftController in Interface Builder file.解决办法,按下图,选择正确的Module3.产生上面错误的原因:在设置好Storyboard后,直接在类文件中,添加或者删除@objc(类名)关键字,导致Storyboard中Module属性没有自动更新,所以一个更通用的解决办法是,让Storyboard自动更新Module,如下:3.3 错误模拟Demo下载为了能够让大家更清楚的了解解决流程,将上面的错误进行了模拟,想动手尝试解决以上问题的同学可以直接下载demo四、Objective-c巧妙调用不兼容的Swift方法在Objective-c中调用Swift类中的方法时,由于部分Swift语法不支持转换,会遇到无法找到对应方法的情况,如下:import UIKitenum HTTPState {case Succed, Failed, NetworkError, ServerError, Others}class ILHTTPRequest: NSObject {class func requestLogin(userName: String, password: String, callb ack: (state: HTTPState) -> (Void)) {dispatch_async(dispatch_get_global_queue(0, 0), { () -> Void in NSThread.sleepForTimeInterval(3)dispatch_async(dispatch_get_main_queue(), { () -> Void incallback(state: HTTPState.Succed)})})}}对应的$(SWIFT_MODULE_NAME)-Swift.h文件为:SWIFT_CLASS("_TtC12ILSwiftTests13ILHTTPRequest")@interface ILHTTPRequest : NSObject- (SWIFT_NULLABILITY(nonnull) instancetype)init OBJC_DESIGNATED_I NITIALIZER;@end从上面的头文件中可以看出,方法requestLogin使用了不支持的Swift枚举,转换时方法被自动忽略掉,有以下两种办法,可以巧妙解决类似问题:4.1 用支持的Swift语法包装在Swift文件中,添加一个可兼容包装方法wrapRequestLogin,注意此方法中不能使用不兼容的类型或者语法import UIKitenum HTTPState: Int {case Succed = 0, Failed = 1, NetworkError = 2, ServerError = 3, O thers = 4}class ILHTTPRequest: NSObject {class func requestLogin(userName: String, password: String, callb ack: (state: HTTPState) -> (Void)) {dispatch_async(dispatch_get_global_queue(0, 0), { () -> Void in NSThread.sleepForTimeInterval(3)dispatch_async(dispatch_get_main_queue(), { () -> Void incallback(state: HTTPState.Succed)})})}class func wrapRequestLogin(userName: String, password: String, c allback: (state: Int) -> (Void)) {self.requestLogin(userName, password: password) { (state) -> (Voi d) incallback(state: state.rawValue)}}}对应的$(SWIFT_MODULE_NAME)-Swift.h文件为:SWIFT_CLASS("_TtC12ILSwiftTests13ILHTTPRequest")@interface ILHTTPRequest : NSObject+ (void)wrapRequestLogin:(NSString * __nonnull)userName password: (NSString * __nonnull)password callback:(void (^ __nonnull)(NSInt eger))callback;- (SWIFT_NULLABILITY(nonnull) instancetype)init OBJC_DESIGNATED_I NITIALIZER;@end此时,我们可以在Objective-c中直接使用包装后的方法wrapRequestLogin4.2 巧妙使用继承使用继承可以支持所有的Swift类型,主要的功能在Objective-c中实现,不支持的语法在Swift 文件中调用,例如,ILLoginSuperController做为父类@interface ILLoginSuperController : UIViewController@property (weak, nonatomic) IBOutlet UITextField *userNameField; @property (weak, nonatomic) IBOutlet UITextField *passwordField; - (IBAction)loginButtonPressed:(id)sender;@end////////////////////////////////////////////////////////////////@implementation ILLoginSuperController- (IBAction)loginButtonPressed:(id)sender{}@end创建Swift文件,继承自ILLoginSuperController,在此Swift文件中调用那些不支持的语法import UIKitclass ILLoginController: ILLoginSuperController {override func loginButtonPressed(sender: AnyObject!) { ILHTTPRequest.requestLogin(erNameField.text, password: sel f.passwordField.text) { (state) -> (Void) in//具体业务逻辑}}}五、多Target编译错误解决在使用多Target时,会出现一些编译错误5.1 Use of undeclared type此类错误,是因为当前运行的Target找不到必须编译文件。