iOS - Swift 与 C 语言交互编程
前言
- 作为一种可与 Objective-C 相互调用的语言,Swift 也具有一些与 C 语言的类型和特性,如果你的代码有需要,Swift 也提供了和常见的 C 代码结构混合编程的编程方式。
1、基本数据类型
Swift 提供了一些和 C 语言的基本类型如
char,int,float,double等价的 Swift 基本数据类型。然而,这些 Swift 的核心基本类型之间并不能隐式的相互转换,如Int。因此,只有你的代码明确要求它们时再使用这些类型,而Int可以在任何你想使用它的时候使用。C 类型 Swift 类型 boolCBoolchar, signed charCCharunsigned charCUnsignedCharshortCShortunsigned shortCUnsignedShortintCIntunsigned intCUnsignedIntlongCLongunsigned longCUnsignedLonglong longCLongLongunsigned long longCUnsignedLongLongwchar_tCWideCharchar16_tCChar16char32_tCChar32floatCFloatdoubleCDouble
2、枚举
Swift 引进了用宏
NS_ENUM来标记的任何 C 风格的枚举类型。这意味着无论枚举值是在系统框架还是在自定义的代码中定义的,当他们导入到 Swift 时,他们的前缀名称将被截断。例如,看这个 Objective-C 枚举:// Objective-C typedef NS_ENUM(NSInteger, UITableViewCellStyle) { UITableViewCellStyleDefault, UITableViewCellStyleValue1, UITableViewCellStyleValue2, UITableViewCellStyleSubtitle };在 Swift 中这样来实现:
// Swift enum UITableViewCellStyle:Int { case Default case Value1 case Value2 case Subtitle }当您需要指向一个枚举值时,使用以点 (.) 开头的枚举名称:
// Swift let cellStyle:UITableViewCellStyle = .DefaultSwift 也引进了标有
NS_OPTIONS宏选项。而选项的行为类似于引进的枚举,选项还可以支持一些位操作,如&,| 和 ~。在 Objective-C 中,你用一个空的选项设置标示恒为零 (0)。在 Swift 中,使用 nil 代表没有任何选项。
3、指针
Swift 尽可能避免让您直接访问指针。然而,当您需要直接操作内存的时候,Swift 也为您提供了多种指针类型。下面的表使用 Type 作为占位符类型名称来表示语法的映射。
对于参数,使用以下映射:
C 句法 Swift 句法 const void *CConstVoidPointervoid *CConstPointer<Type>const Type *CUnsignedCharType *CMutablePointer<Type>对于返回类型,变量和参数类型的多层次指针,使用以下映射:
C 句法 Swift 句法 void *COpaquePointerType *UnsafePointer<Type>对于类(class)类型,使用以下映射:
C 句法 Swift 句法 Type * const *CConstPointer<Type>Type * __strong *CMutablePointer<Type>Type **AutoreleasingUnsafePointer<Type>
1)C 可变指针:
- 当一个函数被声明为接受
CMutablePointer<Type>参数时,这个函数可以接受下列任何一个类型作为参数:nil,作为空指针传入- 一个
CMutablePointer<Type>类型的值 - 一个操作数是
Type类型的左值的输入输出表达式,作为这个左值的内存地址传入 一个输入输出
Type[]值,作为一个数组的起始指针传入,并且它的生命周期将在这个调用期间被延长如果您像这样声明了一个函数:
// Swift func takesAMutablePointer(x:CMutablePointer<Float>) { /*...*/ }那么您可以使用以下任何一种方式来调用这个函数:
// Swift var x:Float = 0.0 var p:CMutablePointer<Float> = nil var a:[Float] = [1.0, 2.0, 3.0] takesAMutablePointer(nil) takesAMutablePointer(p) takesAMutablePointer(&x) takesAMutablePointer(&a)
当函数被声明使用一个
CMutableVoidPointer参数,那么这个函数接受任何和CMutablePointer<Type>相似类型的Type操作数。如果您这样定义了一个函数:
// Swift func takesAMutableVoidPointer(x:CMutableVoidPointer) { /*...*/ }那么您可以使用以下任何一种方式来调用这个函数:
// Swift var x:Float = 0.0, y:Int = 0 var p:CMutablePointer<Float> = nil, q:CMutablePointer<Int> = nil var a:[Float] = [1.0, 2.0, 3.0], b:Int = [1, 2, 3] takesAMutableVoidPointer(nil) takesAMutableVoidPointer(p) takesAMutableVoidPointer(q) takesAMutableVoidPointer(&x) takesAMutableVoidPointer(&y) takesAMutableVoidPointer(&a) takesAMutableVoidPointer(&b)
- 当一个函数被声明为接受
2)C 常指针:
- 当一个函数被声明为接受
CConstPointer<Type>参数时,这个函数可以接受下列任何一个类型作为参数:nil,作为空指针传入- 一个
CMutablePointer<Type>,CMutableVoidPointer,CConstPointer<Type>,CConstVoidPointer,或者在必要情况下转换成CConstPointer<Type>的AutoreleasingUnsafePointer<Type>值 - 一个操作数是
Type类型的左值的输入输出表达式,作为这个左值的内存地址传入 一个
Type[]数组值,作为一个数组的起始指针传入,并且它的生命周期将在这个调用期间被延长如果您这样定义了一个函数:
// Swift func takesAConstPointer(x:CConstPointer<Float>) { /*...*/ }那么您可以使用以下任何一种方式来调用这个函数:
// Swift var x:Float = 0.0 var p:CConstPointer<Float> = nil takesAConstPointer(nil) takesAConstPointer(p) takesAConstPointer(&x) takesAConstPointer([1.0, 2.0, 3.0])
当函数被声明使用一个
CConstVoidPointer参数,那么这个函数接受任何和CConstPointer<Type>相似类型的Type操作数。如果您这样定义了一个函数:
// Swift func takesAConstVoidPointer(x:CConstVoidPointer) { /*...*/ }那么您可以使用以下任何一种方式来调用这个函数:
// Swift var x:Float = 0.0, y:Int = 0 var p:CConstPointer<Float> = nil, q:CConstPointer<Int> = nil takesAConstVoidPointer(nil) takesAConstVoidPointer(p) takesAConstVoidPointer(q) takesAConstVoidPointer(&x) takesAConstVoidPointer(&y) takesAConstVoidPointer([1.0, 2.0, 3.0]) takesAConstVoidPointer([1, 2, 3])
- 当一个函数被声明为接受
3)自动释放不安全指针:
- 当一个函数被声明为接受
AutoreleasingUnsafePointer<Type>参数时,这个函数可以接受下列任何一个类型作为参数:nil,作为空指针传入- 一个
AutoreleasingUnsafePointer<Type>值 其操作数是原始的,复制到一个临时的没有所有者的缓冲区的一个输入输出表达式,该缓冲区的地址传递给调用,并返回时,缓冲区中的值加载,保存,并重新分配到操作数。
注意:这个列表没有包含数组。
如果您这样定义了一个函数:
// Swift func takesAnAutoreleasingPointer(x:AutoreleasingUnsafePointer<NSDate?>) { /*...*/ }那么您可以使用以下任何一种方式来调用这个函数:
// Swift var x:NSDate? = nil var p:AutoreleasingUnsafePointer<NSDate?> = nil takesAnAutoreleasingPointer(nil) takesAnAutoreleasingPointer(p) takesAnAutoreleasingPointer(&x)注意:C 语言函数指针没有被 Swift 引进。
- 当一个函数被声明为接受
4、全局常量
- 在 C 和 Objective-C 语言源文件中定义的全局常量会自动地被 Swift 编译引进并做为 Swift 的全局常量。
5、预处理指令
Swift 编译器不包含预处理器。取而代之的是它充分利用了编译时属性生成配置和语言特性来完成相同的功能。因此 Swift 没有引进预处理指令。
- 1)简单宏
- 在 C 和 Objective-C,您通常使用的 #define 指令定义的一个宏常数,在 Swift,您可以使用全局常量来代替。例如: 一个全局定义
#define FADE_ANIMATION_DURATION 0.35,在 Swift可以使用let FADE_ANIMATION_DURATION = 0.35来更好的表述。由于简单的用于定义常量的宏会被直接被映射成 Swift 全局量,Swift 编译器会自动引进在 C 或 Objective-C 源文件中定义的简单宏。
- 在 C 和 Objective-C,您通常使用的 #define 指令定义的一个宏常数,在 Swift,您可以使用全局常量来代替。例如: 一个全局定义
- 2)复杂宏
- 在 C 和 Objective-C 中使用的复杂宏在 Swift 中并没有与之对应的定义。复杂宏是那些不用来定义常量的宏,而是用来定义包含小括号 () 函数的宏。您在 C 和 Objective-C 使用复杂的宏是用 来避免类型检查的限制和相同代码的重复劳动。然而,宏也会产生 Bug 和重构的困难。在 Swift 中你可以直接使用函数和泛型来达到同样的效果。因此,在 C 和 Objective-C 源文件中定义的复杂宏在 Swift 是不能使用的。
- 3)编译配置
Swift 代码和 Objective-C 代码以不同的方式进行条件编译。Swift 代码可以根据生成配置的评价配进行有条件的编译。生成配置包括
true和false字面值,命令行标志,和下表中的平台测试函数。您可以使用-D <#Flag#>指定命令行标志。函数 有效参数 os()OSX, iOSarch()x86_64, arm, arm64, i386- 注意:
arch(arm)的生成配置不会为 64 位 arm 设备返回true,当代码运行在为 32 位的 iOS 模拟器器时,arch(i386)的生成配置返回true。
- 注意:
一个简单的条件编译需要以下代码格式:
#if build configuration statements #else statements #endif一个由零个或多个有效的 Swift 语句声明的
statements,可以包括表达式,语句和控制流语句。您可以添加额外的构建配置要求,条件编译说明用&&和||操作符以及!操作符,添加条件控制块用#elseif:#if build configuration && !build configuration statements #elseif build configuration statements #else statements #endif与 C 语言编译器的条件编译相反,Swift 条件编译语句必须完全是自包含和语法有效的代码块。这是因为 Swift 代码即使没有被编译,也要全部进行语法检查。
iOS - Swift 与 C 语言交互编程的更多相关文章
- Swift 与 C 语言混合编程
前言 作为一种可与 Objective-C 相互调用的语言,Swift 也具有一些与 C 语言的类型和特性,如果你的代码有需要,Swift 也提供了和常见的 C 代码结构混合编程的编程方式. 1.基本 ...
- iOS: 学习笔记, Swift与C指针交互(译)
Swift与C指针交互 Objective-C和C API经常需要使用指针. 在设计上, Swift数据类型可以自然的与基于指针的Cocoa API一起工作, Swift自动处理几种常用的指针参数. ...
- 从Go、Swift出发:语言的选择需谨慎
本文转自 : http://www.csdn.net/article/2014-12-09/2823025 摘要:无论是开源的Go,还是闭源的Swift,新的语言总是利弊一体.不过可以确定的是,新的语 ...
- iOS开发系列--C语言之基础知识
概览 当前移动开发的趋势已经势不可挡,这个系列希望浅谈一下个人对IOS开发的一些见解,这个IOS系列计划从几个角度去说IOS开发: C语言 OC基础 IOS开发(iphone/ipad) Swift ...
- 为什么还坚持.NET? 找一门适合自己的语言去做编程
为什么还坚持.NET? 找一门适合自己的语言去做编程 接触了.NET快十二年了,现在专注于分布式服务的开发. 中间经历过各种编程语言的诱惑,ios等. 前几年才对自己有比较明确的定位 技术上:找到适合 ...
- iOS Swift 模块练习/swift基础学习
SWIFT项目练习 SWIFT项目练习2 iOS Swift基础知识代码 推荐:Swift学习使用知识代码软件 0.swift中的宏定义(使用方法代替宏) 一.视图 +控件 1.UIImag ...
- Go语言 并发编程
Go语言 并发编程 作者:Eric 微信:loveoracle11g 1.创建goroutine // 并行 是两个队列同时使用两台咖啡机 // 并发 是两个队列交替使用一台咖啡机 package m ...
- swift是强类型语言
swift是强类型语言 所有的变量必须先声明,后使用: 指定类型的变量只能接收类型与之匹配的值. 强类型:变量的类型明确,变量的赋值必须符合类型约束:变量的类型转化必须显式进行. 强类型:类型规则的制 ...
- iOS Swift WisdomHUD 提示界面框架
iOS Swift WisdomHUD 提示界面框架 Framework Use profile(应用简介) 一:WisdomHUD简介 今天给大家介绍一款iOS的界面显示器:WisdomHUD,W ...
随机推荐
- python读入文件
举例说明吧,路径一定要带转义符‘\’,下面的例子中,每一行是一个样本的feature >>> myfile=open("D:\\301\\graduate_thesis\\ ...
- Linux下查看用户列表
cat /etc/passwd 可以查看所有用户的列表 w 可以查看当前活跃的用户列表 cat /etc/group 查看用户组
- 图示-Centos7完整安装
工作过程中,一些未接触过Centos,或未安装过Centos的同事经常会问,如何安装?这个事说简单真简单,只有操作过一次,第二次就能够熟练的自己动手安装:但说难也难,如果没人带,第一次安装的时候确实不 ...
- Ubuntu 14.04下NFS安装配置
1.安装nfs-server # apt-get install nfs-kernel-server 2.建立nfs专用文件夹 # mkdir /data/disk1 3.配置nfs # vi /et ...
- JavaEE基础(二十二)/IO流
1.IO流(序列流) 1.什么是序列流 序列流可以把多个字节输入流整合成一个, 从序列流中读取数据时, 将从被整合的第一个流开始读, 读完一个之后继续读第二个, 以此类推. 2.使用方式 整合两个: ...
- java面试每日一题12
题目:打印出如下图案(菱形) * *** ****** ******** ****** *** * public class Diamond { public static ...
- hbase regionserver IO问题
regionserver日志: java.io.IOException: Connection reset by peer at sun.nio.ch.FileDispatcherIm ...
- noi 2971 抓住那头牛
2971:抓住那头牛 查看 提交 统计 提问 总时间限制: 2000ms 内存限制: 65536kB 描述 农夫知道一头牛的位置,想要抓住它.农夫和牛都位于数轴上,农夫起始位于点N(0<=N ...
- sql server 添加字段并且赋默认值和说明
select soct.Captcha,CreateOn,* from SceneryOrderCheckTicket soctright join (SELECT Captcha,convert(c ...
- java提高篇---HashSet
对于HashSet而言,它是基于HashMap来实现的,底层采用HashMap来保存元素.所以如果对HashMap比较熟悉,那么HashSet是so easy!! 一.定义 public class ...