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 = , 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指针交互(译)的更多相关文章
- iOS: 学习笔记, Swift与Objective-C混用总结
Swift与Objective-C交互总结 在Swift中使用Objective-C(简单) 在创建OjbC文件时, XCode会提示创建XXX-Bridging-Header.h文件, 创建之 在创 ...
- iOS: 学习笔记, Swift与Objective-C混用简明教程(转载)
Swift与Objective-C混用简明教程 转载自:https://github.com/lifedim/SwiftCasts/tree/master/000_mix_swift_objc 我想很 ...
- iOS: 学习笔记, Swift名字空间
在Swift中, 名字空间是用class(extension)嵌套来实现的, 下面用一个简单例子来进行展示 // // main.swift // SwiftNameSpace // // Creat ...
- iOS: 学习笔记, Swift运算符定义
Swift操作符可以自行定义, 只需要加上简单的标志符即可. @infix 中置运算. 如+,-,*,/运算 @prefix 前置运算. 如- @postfix 后置运算. a++, a-- @ass ...
- iOS: 学习笔记, swift扩展
// // YYExtension.swift // // Created by yao_yu on 14-7-18. // Copyright (c) 2014年 yao_yu. All right ...
- iOS: 学习笔记, Swift操作符定义
Swift操作符能够自行定义, 仅仅须要加上简单的标志符就可以. @infix 中置运算. 如+,-,*,/运算 @prefix 前置运算. 如- @postfix 后置运算. a++, a-- @a ...
- IOS学习笔记48--一些常见的IOS知识点+面试题
IOS学习笔记48--一些常见的IOS知识点+面试题 1.堆和栈什么区别? 答:管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制:对于堆来说,释放工作由程序员控制,容易产生memor ...
- iOS学习笔记-自定义过渡动画
代码地址如下:http://www.demodashi.com/demo/11678.html 这篇笔记翻译自raywenderlick网站的过渡动画的一篇文章,原文用的swift,由于考虑到swif ...
- IOS学习笔记25—HTTP操作之ASIHTTPRequest
IOS学习笔记25—HTTP操作之ASIHTTPRequest 分类: iOS2012-08-12 10:04 7734人阅读 评论(3) 收藏 举报 iosios5网络wrapper框架新浪微博 A ...
随机推荐
- 统计学习导论:基于R应用——第三章习题
第三章习题 部分证明题未给出答案 1. 表3.4中,零假设是指三种形式的广告对TV的销量没什么影响.而电视广告和收音机广告的P值小说明,原假设是错的,也就是电视广告和收音机广告均对TV的销量有影响:报 ...
- cocos2d-x学习日志(13) --A星寻路算法demo
你是否在做一款游戏的时候想创造一些怪兽或者游戏主角,让它们移动到特定的位置,避开墙壁和障碍物呢?如果是的话,请看这篇教程,我们会展示如何使用A星寻路算法来实现它! A星算法简介: A*搜寻算法俗称A星 ...
- [TypeScript] Installing TypeScript and Running the TypeScript Compiler (tsc)
This lesson shows you how to install TypeScript and run the TypeScript compiler against a .ts file f ...
- [Ionic] Ionic Quickstart for Windows
1. Install ionic 2. Create ionic app ionic start myApp tabs //create a app cd myApp ionic serve // o ...
- python学习笔记(六)文件夹遍历,异常处理
python学习笔记(六) 文件夹遍历 1.递归遍历 import os allfile = [] def dirList(path): filelist = os.listdir(path) for ...
- 使用like时left outer join和inner join的区别
--select top 10000 * into #s from search set statistics time on set statistics io on select userId,c ...
- C#_ 项目打包附加数据库
C#_ 项目打包附加数据库 2010-07-11 23:22:45| 分类: Winfrom|举报|字号 订阅 实现效果:安装项目时直接附加数据库. 1.首先在需要部 署的项目的解决方案资源 ...
- 亲测git与github
1.安装MyEclipse 8.5,略去不表.2.下载Eclipse的git插件——EGit.下载网址http://download.eclipse.org/egit/updates-1.3/org. ...
- CentOS 6.7安装Tomcat 7
1.下载Tomcat 7 wget http://apache.fayea.com/tomcat/tomcat-7/v7.0.67/bin/apache-tomcat-7.0.67.tar.gz 2. ...
- js常用笔记
此文仅为笔记,代码来源自网络 网络技术文档:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript 1.使用||和&&简化语句, ...