Swift与C语言指针结合使用实例

 更新时间:2015年05月25日 10:45:57   投稿:junjie  
这篇文章主要介绍了Swift与C语言指针结合使用实例,本文讲解了用以输入/输出的参数指针、作为数组使用的参数指针、用作字符串参数的指针、指针参数转换的安全性等内容,需要的朋友可以参考下

Objective-C和C的API常常会需要用到指针。Swift中的数据类型都原生支持基于指针的Cocoa API,不仅如此,Swift会自动处理部分最常用的将指针作为参数传递的情况。这篇文章中,我们将着眼于在Swift中让C语言指针与变量、数组和字符串共同工作。
####用以输入/输出的参数指针

C和Objective-C并不支持多返回值,所以Cocoa API中常常将指针作为一种在方法间传递额外数据的方式。Swift允许指针被当作inout参数使用,所以你可以用符号&将对一个变量的引用作为指针参数传递。举例来说:UIColor中的getRed(_:green:blue:alpha:)方法需要四个CGFloat*指针来接收颜色的组成信息,我们使用&来将这些组成信息捕获为本地变量:

复制代码 代码如下:

var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
color.getRed(&r, green: &g, blue: &b, alpha: &a)

另一种常见的情况是Cocoa中NSError的习惯用法。许多方法会使用一个NSError**参数来储存可能的错误的信息。举例来说:我们用NSFileManager的contentOfDirectoryAtPath(_:error:)方法来将目录下的内容列表,并将潜在的错误指向一个NSError?变量:
复制代码 代码如下:

var maybeError: NSError?
if let contents = NSFileManager.defaultManager()
    .contentsOfDirectoryAtPath("/usr/bin", error: &maybeError) {
    // Work with the directory contents
} else if let error = maybeError {
    // Handle the error
}

为了安全性,Swift要求被使用&传递的变量已经初始化。因为无法确定这个方法会不会在写入数据前尝试从指针中读取数据。

####作为数组使用的参数指针

在C语言中,数组和指针的联系十分紧密,而Swift允许数组能够作为指针使用,从而与基于数组的C语言API协同工作更加简单。一个固定的数组可以使用一个常量指针直接传递,一个变化的数组可以用&运算符将一个非常量指针传递。就和输入/输出参数指针一样。举例来说:我们可以用Accelerate框架中的vDSP_vadd方法让两个数组a和b相加,并将结果写入第三个数组result。

复制代码 代码如下:

import Accelerate

let a: [Float] = [1, 2, 3, 4]
let b: [Float] = [0.5, 0.25, 0.125, 0.0625]
var result: [Float] = [0, 0, 0, 0]

vDSP_vadd(a, 1, b, 1, &result, 1, 4)

// result now contains [1.5, 2.25, 3.125, 4.0625]

#用作字符串参数的指针

C语言中用cont char*指针来作为传递字符串的基本方式。Swift中的String可以被当作一个无限长度UTF-8编码的const char*指针来传递给方法。举例来说:我们可以直接传递一个字符串给一个标准C和POSIX库方法

复制代码 代码如下:

puts("Hello from libc")
let fd = open("/tmp/scratch.txt", O_WRONLY|O_CREAT, 0o666)

if fd < 0 {
    perror("could not open /tmp/scratch.txt")
} else {
    let text = "Hello World"
    write(fd, text, strlen(text))
    close(fd)
}

#指针参数转换的安全性

Swift很努力地使与C语言指针的交互更加便利,因为它们广泛地存在于Cocoa之中,同时保持一定的安全性。然而,相比你的其他Swift代码与C语言的指针交互具有潜在的不安全性,所以务必要小心使用。其中特别要注意:

●如果被调用者为了在其返回值之后再次使用而保存了C指针的数据,那么这些转换使用起来并不安全。转换后的指针仅在调用期间保证有效。甚至你将同样的变量、数组或字符串作为多指针参数再次传递,你每次都会收到一个不同的指针。这个异常将全局或静态地储存为变量。你可以安全地将这段地址当作永久唯一的指针使用。例如:作为一个KVO上下文参数使用的时候。

●当指针类型为Array或String时,溢出检查不是强制进行的。 基于C语言的API无法增加数组和字符串大小,所以在你将其传递到基于C语言的API之前,你必须确保数组或字符的大小正确。

如果你需要使用基于指针的API时没有遵守以上指导,或是你重写了接受指针参数的Cocoa方法,于是你可以在Swift中直接用不安全的指针来使用未经处理的内存。在未来的文章中我们将着眼于更加高级的情况。

相关文章

  • SwiftUI图片缩放、拼图等处理教程

    SwiftUI图片缩放、拼图等处理教程

    SwiftUI是一种使用Swift语言在苹果设备上构建用户界面的创新且简单的方式,下面这篇文章主要给大家介绍了关于SwiftUI图片缩放、拼图等处理的相关资料,需要的朋友可以参考下
    2021-08-08
  • Swift使用编解码库Codable的过程详解

    Swift使用编解码库Codable的过程详解

    Codable 是 Swift 引入的全新的编解码库,使开发者更方便的解析JSON 或 plist 文件,支持枚举、结构体和类,这篇文章主要介绍了Swift使用编解码库Codable,需要的朋友可以参考下
    2023-09-09
  • SwiftUI中TabView组件的常规使用

    SwiftUI中TabView组件的常规使用

    这篇文章主要给大家介绍了关于SwiftUI中TabView组件的常规使用,文中通过实例代码介绍的非常详细,对大家学习或者使用SwiftUI具有一定的参考学习价值,需要的朋友可以参考下
    2022-06-06
  • 详解Swift中的数据类型类型转换

    详解Swift中的数据类型类型转换

    Swift中的类型转换可以结合类的继承等面向对象的编程特性来进行,本文中我们就来详解Swift中的数据类型类型转换,需要的朋友可以参考下
    2016-07-07
  • Swift教程之方法详解

    Swift教程之方法详解

    这篇文章主要介绍了Swift教程之方法详解,方法是关联到一个特定类型的函数,类、结构、枚举所有可以定义实例方法,封装特定任务和功能处理给定类型的一个实例,需要的朋友可以参考下
    2015-01-01
  • Swift心得笔记之运算符

    Swift心得笔记之运算符

    区别于 C 语言,在 Swift 中你可以对浮点数进行取余运算(%),Swift 还提供了 C 语言没有的表达两数之间的值的区间运算符,(a..b和a...b),这方便我们表达一个区间内的数值。
    2015-04-04
  • Swift 3.0基础学习之下标

    Swift 3.0基础学习之下标

    这篇文章主要介绍了Swift 3.0基础学习之下标的相关资料,文中介绍的非常详细,对大家学习或者使用swift具有一定的参考价值,需要的朋友下面来一起看看吧。
    2017-03-03
  • Swift中内置的集合类型学习笔记

    Swift中内置的集合类型学习笔记

    Swift中自带数组、set、字典三大集合类型,这里将学习过程中的基础的Swift中内置的集合类型学习笔记进行整理,需要的朋友可以参考下
    2016-06-06
  • Swift 中闭包的简单使用

    Swift 中闭包的简单使用

    这篇文章主要介绍了Swift 中闭包的简单使用的相关资料,需要的朋友可以参考下
    2016-10-10
  • swift实现自定义圆环进度提示效果

    swift实现自定义圆环进度提示效果

    这篇文章主要为大家详细介绍了swift实现自定义圆环进度提示效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-05-05

最新评论