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 = , g:Float = , b:Float = , a:Float =
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] = [, , , ]
let b: [Float] = [0.5, 0.25, 0.125, 0.0625]
var result: [Float] = [, , , ] vDSP_vadd(a, , b, , &result, , ) // 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 < {
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指针操作内存. 我们会在将来的文章中看到更多高级应用.

iOS: 学习笔记, Swift与C指针交互(译)的更多相关文章

  1. iOS: 学习笔记, Swift与Objective-C混用总结

    Swift与Objective-C交互总结 在Swift中使用Objective-C(简单) 在创建OjbC文件时, XCode会提示创建XXX-Bridging-Header.h文件, 创建之 在创 ...

  2. iOS: 学习笔记, Swift与Objective-C混用简明教程(转载)

    Swift与Objective-C混用简明教程 转载自:https://github.com/lifedim/SwiftCasts/tree/master/000_mix_swift_objc 我想很 ...

  3. iOS: 学习笔记, Swift名字空间

    在Swift中, 名字空间是用class(extension)嵌套来实现的, 下面用一个简单例子来进行展示 // // main.swift // SwiftNameSpace // // Creat ...

  4. iOS: 学习笔记, Swift运算符定义

    Swift操作符可以自行定义, 只需要加上简单的标志符即可. @infix 中置运算. 如+,-,*,/运算 @prefix 前置运算. 如- @postfix 后置运算. a++, a-- @ass ...

  5. iOS: 学习笔记, swift扩展

    // // YYExtension.swift // // Created by yao_yu on 14-7-18. // Copyright (c) 2014年 yao_yu. All right ...

  6. iOS: 学习笔记, Swift操作符定义

    Swift操作符能够自行定义, 仅仅须要加上简单的标志符就可以. @infix 中置运算. 如+,-,*,/运算 @prefix 前置运算. 如- @postfix 后置运算. a++, a-- @a ...

  7. IOS学习笔记48--一些常见的IOS知识点+面试题

      IOS学习笔记48--一些常见的IOS知识点+面试题   1.堆和栈什么区别? 答:管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制:对于堆来说,释放工作由程序员控制,容易产生memor ...

  8. iOS学习笔记-自定义过渡动画

    代码地址如下:http://www.demodashi.com/demo/11678.html 这篇笔记翻译自raywenderlick网站的过渡动画的一篇文章,原文用的swift,由于考虑到swif ...

  9. IOS学习笔记25—HTTP操作之ASIHTTPRequest

    IOS学习笔记25—HTTP操作之ASIHTTPRequest 分类: iOS2012-08-12 10:04 7734人阅读 评论(3) 收藏 举报 iosios5网络wrapper框架新浪微博 A ...

随机推荐

  1. 5种Web常见编码、变换算法的自动识别

    #coding=utf-8 #识别字符序列变换算法,当前支持标准的MD5.SHA-1.Base64,及主流的URL编码.HTML编码 import re import sys #MD5判断函数 def ...

  2. Android中shape属性详解

    一.简单使用 刚开始,就先不讲一堆标签的意义及用法,先简单看看shape标签怎么用. 1.新建shape文件 首先在res/drawable文件夹下,新建一个文件,命名为:shape_radius.x ...

  3. Java编程性能优化一

    转自:http://my.oschina.net/xianggao/blog/77224 在JAVA程序中,性能问题的大部分原因并不在于JAVA语言,而是程序本身.养成良好的编码习惯非常重要,能够显著 ...

  4. MySQL数据库事务剖析

    MySQL数据库事务剖析 事务就是一组原子性的SQL查询,是一个独立的执行单元.事务内的语句,要么全部执行成功,要么全部执行失败. 1.事务的标准特征 一个运行良好的事务处理系统,必须具备原子性.一致 ...

  5. 64位开源处理器Rocket该人士介绍

    最近大概读一点UCB发布时间Rocket处理器的源代码,的每个文件的源代码的功能有一定的一般理解,Mark一点点. Rocket是一家64bit标量处理器,5第一阶段管道,用途risc-v指令集.综合 ...

  6. careercup-数组和字符串1.2

    1.2 用C或C++实现void reverse(char *str)函数,即反转一个null结尾的字符串. C++实现代码: #include<iostream> #include< ...

  7. xcode语法高亮插件

    转自http://www.cocoachina.com/bbs/read.php?tid=150107 首先感谢该楼主的亲情贡献@不胜感激! 在Xcode4.6.3中,我使用如下方法放到Plugins ...

  8. /bin/bash^M: bad interpreter: 没有那个文件或目录--转载

    运行脚本时出现了这样一个错误,打开之后并没有找到所谓的^M,查了之后才知道原来是文件格式的问题,也就是linux和windows之间的不完全兼容...具体细节不管,如果验证: vim test.sh: ...

  9. float浮动之后高度自适应失效解决方案

    float浮动之后高度自适应失效解决方案 >>>>>>>>>>>>>>>>>>>> ...

  10. Bootstrap--全局css样式之表单

    单独的表单控件会被自动赋予一些全局样式.所有设置了 .form-control 类的 <input>.<textarea> 和 <select> 元素都将被默认设置 ...