博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS: 学习笔记, Swift与C指针交互(译)
阅读量:5150 次
发布时间:2019-06-13

本文共 2509 字,大约阅读时间需要 8 分钟。

Swift与C指针交互

Objective-C和C API经常须要使用指针. 在设计上, Swift数据类型能够自然的与基于指针的Cocoa API一起工作, Swift自己主动处理几种经常使用的指针參数. 在本文中, 我们将看到C中的指针參数怎样与Swift中的变量,数组,字符串一起工作.

指针作为输入/输出參数

C和Objective-C不支持多个返回值, 所以Cocoa API常常使用指针传递附加參数到函数. Swift同意把指针參数看成[inout]參数, 所以你能够用相同的&语法传递一个变量的引用作为指针. 比如: UIColor的getRed(_:green:blue:alpha:)方法使用4个CGFloat*指针来接受颜色的组合. 我们能够用&来得到这些值:

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

还有一个常常使用的是NSError. 很多方法使用了NSError*參数来保存发生的错误. 比如: 我们列举文件夹里的内容使用NSFileManager的contentsOfDirectoryAtPath(_:error:)方法, 直接使用NSError?变量来保存可能的错误:

var maybeError:NSError?  if let contents = NSFileManager.defaultManager().contentsOfDirectoryAtPath("/usr/bin", error: &maybeError){      //内容处理      for i in contents{          println(i)      }  }else if let error = maybeError{      //错误处理      println(error.description)  }

安全起见, Swift要求变量在使用&前须要初始化. 由于它不知道被调用的方法是否在改动它之前会读取指针

数组指针

在C中数组与指针紧紧相连. 为方便使用基于数组的C API, Swift同意将Array作为指针. 不可改动数组能够直接当成常量指针, 可改动数组能够使用&操作符做为很量指针(就和inout參数一样). 比如: 我们把两个数组 a 和 b 使用vDSP_vadd函数(Accelerte framework)相加, 把结果写到第三个数组 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*指针, 它会给函数传递一个 null结束, 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指针的交互方便并提供了一定的安全性, 由于C指针无处不在. 可是, 与C指针交互相对于Swift代码来说还是内存的不安全, 因此须要特别注意. 特别的:
* These conversions cannot safely be used if the callee saves the pointer value for use after it returns. The pointer that results from these conversions is only guaranteed to be valid for the duration of a call. Even if you pass the same variable, array, or string as multiple pointer arguments, you could receive a different pointer each time. An exception to this is global or static stored variables. You can safely use the address of a global variable as a persistent unique pointer value, e.g.: as a KVO context parameter.
* Array和String指针没有边界检查. C API不会扩大数组和字符串, 因此在调用前你须要为它分配足够的大小
假设上面的指南不满足你指针交互的须要, 或者你想手动控制指针參数, 你能够直接使用unsafe指针操作内存. 我们会在将来的文章中看到很多其它高级应用.

转载于:https://www.cnblogs.com/yxwkf/p/4082163.html

你可能感兴趣的文章
淘宝JAVA中间件Diamond详解(一)---简介&快速使用
查看>>
Hadoop HBase概念学习系列之HBase里的宽表设计概念(表设计)(二十七)
查看>>
Kettle学习系列之Kettle能做什么?(三)
查看>>
【Mac + GitHub】之在另一台Mac电脑上下载GitHub的SSH链接报错
查看>>
Day03:Selenium,BeautifulSoup4
查看>>
awk变量
查看>>
mysql_对于DQL 的简单举例
查看>>
35. Search Insert Position(C++)
查看>>
[毕业生的商业软件开发之路]C#异常处理
查看>>
一些php文件函数
查看>>
jQuery 给div绑定单击事件
查看>>
Exceptionless 生产部署笔记
查看>>
有关快速幂取模
查看>>
Linux运维必备工具
查看>>
字符串的查找删除
查看>>
NOI2018垫底记
查看>>
快速切题 poj 1002 487-3279 按规则处理 模拟 难度:0
查看>>
Codeforces Round #277 (Div. 2)
查看>>
【更新】智能手机批量添加联系人
查看>>
NYOJ-128前缀式计算
查看>>