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. Linux编辑器的选择使用

    在执行 crontab -e的时候 发现编辑器不对 用的是nano 立刻 sudo select-editor 然后终端返回 Select an editor. To change later, ru ...

  2. ZBar只扫描二维码/条形码

    You can add these codes for ImageScanner scanner.setConfig(0, Config.ENABLE, 0); //Disable all the S ...

  3. c# 请问如何将四个RadioButton分成两组?

    WinForm 只要放在同一个容器中的RadioButton 就自动互斥 创建两个panel容器,分别放两个RadioButton 就是两组了

  4. mybatis12 Usermapper.xml

    输入和输出映射 通过parameterType完成输入映射,通过resultType和resultMap完成输出映射. 1.1parameterType传递pojo包装对象 可以定义pojo包装类型扩 ...

  5. WebService学习笔记系列(二)

    soap(简单对象访问协议),它是在http基础之上传递xml格式数据的协议.soap协议分为两个版本,soap1.1和soap1.2. 在学习webservice时我们有一个必备工具叫做tcpmon ...

  6. AndroidStudio怎么将开源项目发布到jcenter

    前言 自己在网上搜了一大堆,大体就两种方法,而我选择的是其中代码少的的方法,不过他们或多或少留下了少许的坑,(按他们的方法我是上传成功,但不能发布到jCenter上去,也可能是我自己的问题o(≧v≦) ...

  7. MSDN Webcast 系列课程

    云计算(Cloud) 云起龙骧系列课程 网络开发(Web) ASP.NET 4 风云之旅系列课程 ASP.NET 开发实践系列课程 MOSS2007 最佳实战 StepByStep 系列课程 Silv ...

  8. Android pulltorefresh引用遇到的一个问题

    今天在使用pulltorefresh插件的时候遇到了一个让人头疼的问题,在Eclipse中导入要用到的library项目,然后新建一个项目引入Library,显示的是引入成功,如图 而且project ...

  9. Android 网络视频播放器

    项目概要: 1.登录界面 2.播放列表 3.播放界面

  10. MVP快速开发框架

    所谓MVP(Model-View-Presenter)模式.是将APP的结构分为三层: view - UI显示层 view 层主要负责: 提供UI交互 在presenter的控制下修改UI. 将业务事 ...