iOS: 学习笔记, Swift与C指针交互(译)

iOS: 学习笔记, Swift与C指针交互(译)

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

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 = 0
color.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://javaforall.net/118055.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 漏洞扫描和渗透性测试_漏洞扫描软件有哪些

    漏洞扫描和渗透性测试_漏洞扫描软件有哪些目录1.nessus2.AWVS3.WPscan1.nessus1.Nessus软件是什么?如图,我们可以从百度百科得知:Nessus是全世界最多人使用的系统漏洞扫描与分析软件。总共有超过75,000个机构使用Nessus作为扫描该机构电脑系统的软件。2.Nessus软件的安装1.下载地址DownloadNessus|Tenable®https://www.tenable.com/downloads/nessus如图所示,这个是下载官网。我们以..

    2025年11月7日
    3
  • 2020年1月全国程序员工资统计,平均工资13632元。

    2020年1月全国程序员工资统计,平均工资13632元。

    2022年2月12日
    144
  • typeid与decltype[通俗易懂]

    typeid与decltype[通俗易懂]C++在C++98标准中就部分支持动态类型了,C++98对动态类型支持就是C++中的运行时类型识别RTTI。RTTI的机制是为每个类型产生一个type_info类型的数据,程序员可以在程序中使用typeid随时查询一个变量的类型,typeid就会返回变量相应的type_info数据,而type_info的name成员函数可以返回类型的名字。而在C++11中,又增加了hash_code这个成员函…

    2025年10月14日
    2
  • 如何配置java环境变量_java环境变量怎么配置

    如何配置java环境变量_java环境变量怎么配置我们在学习java的时候,必须先来配置一下java的环境变量,也许你不懂什么是java环境变量,我们也不需要懂,你只要知道,java环境变量配置好了,你的电脑就能编译和运行java程序了,这显然是你想要的,好了,下面请跟我一起来做吧!1.首先,我们需要下载JDK安装包,你可以在www.sun.java.com上下载2.然后安装jdk,在安装的过程中选择【开发工具】,记住JDK安装位置。由于这个比较…

    2022年7月8日
    31
  • CentOs安装Python3.9

    CentOs安装Python3.9下载python3源码包wgethttps://www.python.org/ftp/python/3.9.0/Python-3.9.0.tgz或者python官网下载https://www.python.org/ftp/python/3.9.0/Python-3.9.0.tgz然后放过去解压缩源码包tar-zxvfPython-3.9.0.tgz进入源码包文件夹cdPython-3.9.0编译且安装进入源码包目录ls查看源码包内容释放编译文件Makefile.

    2022年6月16日
    99
  • clone() 方法

    clone() 方法

    2021年10月18日
    49

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号