美文网首页程序员说学习编程swift
在Swift中使用C语言的指针

在Swift中使用C语言的指针

作者: DevTalking | 来源:发表于2014-12-12 15:42 被阅读187次

Objective-C和C语言经常需要使用到指针。Swift中的数据类型由于良好的设计,使其可以和基于指针的C语言API无缝混用。同时Swift也可以自动处理大多数将指针作为参数的情况。在这篇文章里,我们可以看到在Swift语言中如何将变量、数组、字符串当做C语言中的指针参数来使用。

将输入输出参数作为指针参数

C和Objective-C不支持多类型的返回值。所以Cocoa API就使用指针作为函数的输入输出参数,以用来传递多类型的数据。Swift允许使用指针参数进行类似inout参数的处理,所以你可以使用&语法将一个var变量的引用作为指针参数进行传递。比如说,UIColorgetRed(_:green:blue:alpha:)方法,使用4个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类的contentsOfDirectoryAtPath(_: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要求在使用&传值时,变量必须是已经被初始化的。这是因为Swift无法知道也无法判断在操作指针之前,该指针是否确实在内存有指向的地址。

将数组作为指针参数

在C语言中,指针与数组是水乳交融,纠缠不清的。那么为了在Swift中能无缝的使用C语言中基于数组的一些API,Swift允许将Array作为指针参数。一个不可变数组的值可以作为一个const指针参数直接传递,可变数组可以使用&作为一个非const指针参数进行传递,就inout参数一样。比如,我们使用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语言中,传递字符串的主要方式是通过const char*指针。在Swift中,String也可以被用作const char*指针,用它可以向函数传递空字符串或UTF-8编码的字符串。比如,我们可以在标准的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是一个类型安全的语言,对指针参数的转换的安全性也有保障,但是相比Swift原生的其他代码来说,还是存在着一定的不安全性。所以我们在使用时要格外小心。比如说:

  • 如果调用者在指针返回之后保存了指针指向的对象,那么再去使用这个对象时是不安全的。这些被转换的指针参数只能在调用过程中或者发送消息过程中保证其有效性。即时你使用相同的变量、数组或者字符串作为多指针参数进行传递,你每次接收到的指针都是不同的。除非是全局或者静态变量。你可以安全的使用全局或静态变量的指针的参数,比如KVO上下文参数。
  • 当将数组或字符串作为指针参数传递时,Swift不会检查其边界值。在C语言中,数组和字符串的大小是不能增长的,所以当你将数组或字符串作为指针参数传递时,要确保它们有足够的大小,或者适合当前场景的大小。

如果你使用的基于指针的API不在这篇指导内,或者你需要重写接收指针参数的Cocoa方法,那么你可以直接使用Swift原始内存中的不安全的指针。我们会在以后的文章中介绍更多Swift的特性。

本文首发地址:在Swift中使用C语言的指针

相关文章

  • 在Swift中使用C语言的指针

    在Swift中使用C语言的指针 在Swift中使用C语言的指针

  • 纯代码讲解swift的指针

    swift的指针: Objective-C和C语言经常需要使用到指针。Swift中的数据类型由于良好的设计,...

  • 在Swift中使用C语言的指针

    Objective-C和C语言经常需要使用到指针。Swift中的数据类型由于良好的设计,使其可以和基于指针的C语言...

  • C语言05- 指针

    C语言05- 指针 13:指针 指针是C语言中的精华,也是C语言程序的重点和难点。 13.1:指针定义与使用 指针...

  • 02-C语言的指针

    02-C语言的指针 目标 C语言指针释义 指针用法 指针与数组 指针与函数的参数 二级指针 函数指针 指针在C中很...

  • [初学C++]浅谈C C++引用和指针的联系和区别

    为什么C/C++语言使用指针? ①一方面,每一种编程语言都使用指针。不止C/C++使用指针。每一种编程语言都使用指...

  • Go语言-指针

    Go语言中的指针不同于C语言,Go语言的指针使用方法要简单很多。当然和C语言从指针定义到指针的使用都有很大的不同。...

  • c++之reference(引用)

    ■在C语言中,使用指针(Pointer) 可以间接获取、修改某个变量的值■在C+ +中,使用引用(Referenc...

  • Swift探索(四): 指针和内存管理

    一:指针 1. 指针的定义 Swift 中引用了某个引用类型实例的常量或变量,与 C 语言中的指针类似,不过它并不...

  • C++: 引用(reference)

    介绍 在C语言中,使用指针(Pointer)可以间接获取、修改某个变量的值;在C++中,使用引用(Referenc...

网友评论

    本文标题:在Swift中使用C语言的指针

    本文链接:https://www.haomeiwen.com/subject/ppgntttx.html