广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >Swift超详细讲解指针
  • 415
分享到

Swift超详细讲解指针

Swift 指针Swift 指针操作 2022-11-13 13:11:32 415人浏览 八月长安
摘要

目录Swift指针Unsafe Pointer对照Objective-C例子Swift指针Unsafe Pointer 如果不是只读,可以修改 ( 写入 ),就加一个 Mutable

Swift指针Unsafe Pointer

如果不是只读,可以修改 ( 写入 ),就加一个 Mutable,

如果没有具体的类型( 通过泛型的方式 ),就加一个 Raw,

如果不是一个单独的对象 ( 指向集合类型 ),就加上 buffer.

Unsafe [ Mutable ] [ Raw ] [ Buffer ] Pointer [ ]

苹果没有编译保护的 [ 可变的 ] [没有类型的] [ 是集合的 ] 指针 [< 具体的类型 >]

对照Objective-C

  • swift 的 unsafeMutablePointer<T>: OC 的 T *
  • swift 的 unsafePointer<T>: OC 的 const T *
  • swift 的 unsafeRawPointer: OC 的 const void *
  • swift 的 unsafeMutableRawPointer: OC 的 void *

例子

例子 1, 无类型的指针

let count = 2
let stride = MemoryLayout<Int>.stride
let alignment = MemoryLayout<Int>.alignment
let byteCount = stride * count
do {
  print("Raw pointers")
  let pointer = UnsafeMutableRawPointer.allocate(
    byteCount: byteCount,
    alignment: alignment)
    // 指针的创建,与销毁
  defer {
     // 需要手动管理,指针的内存
    pointer.deallocate()
  }
  // store 存值
  pointer.storeBytes(of: 42, as: Int.self)
  // 指针需要移动 stride,才能到达下一个指针
  pointer.advanced(by: stride).storeBytes(of: 6, as: Int.self)
  // (pointer+stride).storeBytes(of: 6, as: Int.self), 这个是另一种方式
  // load 取值
  print(pointer.load(as: Int.self))
  print(pointer.advanced(by: stride).load(as: Int.self))
  // 集合的指针
  let bufferPointer = UnsafeRawBufferPointer(start: pointer, count: byteCount)
  for (index, byte) in bufferPointer.enumerated() {
    print("byte \(index): \(byte)")
  }
}

2, 具体类型的指针

具体类型的指针,可以通过指针的 pointee 属性,方便的操作 load 和 store

let count = 2
let stride = MemoryLayout<Int>.stride
let alignment = MemoryLayout<Int>.alignment
let byteCount = stride * count
do {
  print("Typed pointers")
  let pointer = UnsafeMutablePointer<Int>.allocate(capacity: count)
  pointer.initialize(repeating: 0, count: count)
  // 与上面的一样,指针的内存,需要手动管理
  defer {
    pointer.deinitialize(count: count)
    pointer.deallocate()
  }
  pointer.pointee = 42
   // 因为编译器做了优化,指针到达下一个指针,不需要移动 stride
   // 指针移动 1 ,就到了下一个指针
  pointer.advanced(by: 1).pointee = 6
  print( pointer.pointee )
  print(pointer.advanced(by: 1).pointee)
  let bufferPointer = UnsafeBufferPointer(start: pointer, count: count)
  for (index, value) in bufferPointer.enumerated() {
    print("value \(index): \(value)")
  }
}

例子 3: 通过绑定内存,来做指针的转化

bindMemory

let count = 2
let stride = MemoryLayout<Int>.stride
let alignment = MemoryLayout<Int>.alignment
let byteCount = stride * count
do {
  print("Converting raw pointers to typed pointers")
  let rawPointer = UnsafeMutableRawPointer.allocate(
    byteCount: byteCount,
    alignment: alignment)
  defer {
    rawPointer.deallocate()
  }
  // 这一步,将任意指针,转化为类型指针
  let typedPointer = rawPointer.bindMemory(to: Int.self, capacity: count)
  typedPointer.initialize(repeating: 0, count: count)
  defer {
    typedPointer.deinitialize(count: count)
  }
  typedPointer.pointee = 42
  typedPointer.advanced(by: 1).pointee = 6
   // 看结果
  print(typedPointer.pointee)
  print(typedPointer.advanced(by: 1).pointee)
  let bufferPointer = UnsafeBufferPointer(start: typedPointer, count: count)
  for (index, value) in bufferPointer.enumerated() {
    print("value \(index): \(value)")
  }
}

例子 4, 查看指针的字节

struct Demo{
  let number: UInt32
  let flag: Bool
}
do {
  print("Getting the bytes of an instance")
  var one = Demo(number: 25, flag: true)
  withUnsafeBytes(of: &one) { bytes in
    for byte in bytes {
      print(byte)
    }
  }
}

例子 4.1, 指针的字节, 算 check sum

struct Demo{
  let number: UInt32
  let flag: Bool
}
do {
  print("Checksum the bytes of a struct")
  var one = Demo(number: 25, flag: true)
  let checksum = withUnsafeBytes(of: &one) { (bytes) -> UInt32 in
    return ~bytes.reduce(UInt32(0)) { $0 + numericCast($1) }
  }
  print("checksum", checksum) //  checksum 4294967269
}

checeSum 的使用,分为 checeSum 的计算与校验

本文简单描述 checeSum 的计算

数据块,分为 n 个包, size 相同

拿包的字节,计算 checkSum, checkSum 的大小限制在包的 size

例子 5, 获取变量的指针

var cat = "fly"
// 返回的是,闭包中的参数
// withUnsafePointer , 把闭包里面的结果,rethrow 出去 ( 相当于 return 出来 )
let warrior = withUnsafePointer(to: &cat, { $0 })
print(warrior.pointee)

例子 6, 指向多个元素的指针

struct Cat{
    var habit = "eat"
    var paws = 6
    var name = "load"
}
let ptr = UnsafeMutablePointer<Cat>.allocate(capacity: 2) // 指向两个 Cat 结构体
ptr.initialize(repeating: Cat(), count: 2)
defer{
    ptr.deinitialize(count: 2)
    ptr.deallocate()
}
var one = Cat()
one.paws = 8
ptr[1] = one
// 以下两个等价
print(ptr[0])
print(ptr.pointee)
// 下面 3 个等价
print(ptr[1])
print((ptr + 1).pointee)
print(ptr.successor().pointee)

例子 7: 元素组合的探索

var pair = (66, 666)
func test(ptr: UnsafePointer<Int>){
    print(ptr.pointee)
    print(ptr.successor().pointee)
}
withUnsafePointer(to: &pair) { (tuplePtr: UnsafePointer<(Int, Int)>) in
    // 假定内存绑定,不需要经过内存检查
    test(ptr: UnsafeRawPointer(tuplePtr).assumingMemoryBound(to:Int.self))
}

参考了 Unsafe Swift: Using Pointers and Interacting With C

到此这篇关于Swift超详细讲解指针的文章就介绍到这了,更多相关Swift指针内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Swift超详细讲解指针

本文链接: https://www.lsjlt.com/news/171458.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Swift超详细讲解指针
    目录Swift指针Unsafe Pointer对照Objective-C例子Swift指针Unsafe Pointer 如果不是只读,可以修改 ( 写入 ),就加一个 Mutable...
    99+
    2022-11-13
    Swift 指针 Swift 指针操作
  • C++超详细讲解智能指针
    目录一、内存泄漏-永恒的话题二、深度思考三、智能指针分析四、小结一、内存泄漏-永恒的话题 动态申请堆空间,用完后不归还C++ 语言中没有垃圾回收的机制指针无法控制所指堆空间的生命周期...
    99+
    2022-11-13
  • C++超详细讲解引用和指针
    目录引用概念定义步骤引用必须初始化引用初始化后不能更改引用作为函数的参数可以替代指针变量常引用引用作为函数的返回值类型引用的本质指针的引用(了解)指针和引用的区别引用概念 引用的本质...
    99+
    2022-11-13
  • c++智能指针的超详细讲解
    目录1.什么是智能指针2.原始指针的问题3.unique_ptr4.shared_ptr5.shared_ptr使用需要注意的点5.1 不能将一个原始指针初始化多个shared_pt...
    99+
    2022-11-13
  • C语言指针超详细讲解上篇
    目录前言1、指针是什么1.1 指针变量1.2 指针是内存中一个最小单元的编号2、指针和指针类型2.1 指针±类型2.2 指针的解引用2.2.1 int* 类型的解引用2...
    99+
    2022-11-13
  • C语言指针超详细讲解下篇
    目录前言指针运算指针±整数指针-指针指针的关系运算指针和数组二级指针指针数组举例 1举例 2总结前言 本文接着上一篇内容,继续学习指针相关知识点。 指针运算 指针&pl...
    99+
    2022-11-13
  • C语言超详细讲解指针的使用
    目录指针概述自身类型指向类型代码例子数值型指针字符型指针单字符字符数组字符串型指针字符数组总结指针概述 C语言中指针也可以认为是一种类型,不同于数值型和字符型的类型。推演过去指针变量...
    99+
    2022-11-13
  • C语言超详细讲解指向函数的指针
    目录一、函数的指针二、指向函数的指针变量三、调用函数的两种方式四、指向函数的指针的作用五、用指向函数的指针作函数参数(重点)六、为什么要将指向函数的指针变量作为函数的形参(重点)一、...
    99+
    2022-11-13
  • C语言超详细讲解指针与结构体
    目录本节目标初识指针1、内存与地址2、变量的地址3、指针变量4、指针的使用5、指针变量的大小初识结构体1、什么是结构体2、结构体的定义3、结构体的使用本节目标 理解内存与地址的相关概...
    99+
    2022-11-13
  • C语言超详细讲解宏与指针的使用
    目录1、关于define2、初识指针(1)内存(2)示例(3)指针的使用示例(4)指针变量的大小1、关于define define是一个预处理指令,有两种用法,一种是用define定...
    99+
    2022-11-13
  • C语言超详细讲解函数指针的运用
    目录前言计算器的例子回调函数转移表前言 前面我们学习了各种各样的指针类型,有些指针可以说是稀奇百怪,特别是函数指针,有些朋友可能觉得,函数指针有些多余,调用函数为什么要用指针调用,直...
    99+
    2022-11-13
  • C语言超详细讲解指针的概念与使用
    目录一、指针与一维数组1. 指针与数组基础2. 指针与数组3. 一个思考二、指针与字符串三、指针和二维数组1. 指针数组与数组指针2. 指针数组3. 数组指针一、指针与一维数组 1....
    99+
    2022-11-13
  • C++超详细讲解内存空间分配与this指针
    目录成员属性和函数的存储空对象成员属性的存储成员函数的存储this指针的概念解决名称冲突返回对象指针*this总结成员属性和函数的存储 在C++中成员变量和成员函数是分开存储的; 空...
    99+
    2022-11-13
  • SpringCloudNetflixRibbon超详细讲解
    目录一、Ribbon简介1、什么是Ribbon2、Ribbon能干什么二、使用Ribbon1、客户端导入依赖2、application.yml配置3、Controller配置4、Co...
    99+
    2022-11-13
    SpringCloud Netflix Ribbon SpringCloud Ribbon
  • AndroidLayerDrawable超详细讲解
    目录1. 前言2. 实例1. 前言 Android LayerDrawble 包含一个Drawable数组,系统将会按照这些Drawable对象的数组顺序来绘制他们,索引最大的 Dr...
    99+
    2022-11-13
    Android LayerDrawable Android LayerDrawable原理
  • AndroidSwipeRefreshLayout超详细讲解
    目录1. 控件说明2. API介绍3. 使用方法3.1 布局文件3.2 界面代码4. 注意事项1. 控件说明 SwipeRefreshLayout是google官方推荐使用的下拉刷新...
    99+
    2022-11-13
    Android SwipeRefreshLayout Android SwipeRefreshLayout控件
  • Spring针对AOP详细讲解
    目录什么是Spring AOP为什么要用AOP?AOP的组成Spring AOP的实现导入依赖定义切面和切点定义通知Advice(5类)什么是Spring AOP AOP是面向切面编...
    99+
    2022-11-13
  • C语言详细讲解指针数组的用法
    目录1. 指针数组定义方法2. 指针的指针(二级指针)3. 字符串和指针4. 数组指针定义方法数组指针的用法1. 指针数组定义方法 格式: 类型说明符 *数组名[ 元素个数 ] in...
    99+
    2022-11-13
  • Java详细讲解分析双指针法的使用
    目录前言1.判断链表是否有环2.查找链表中间的元素3.奇偶排序前奇后偶4.删除排序链表的重复元素5.三数之和6.分割链表7.合并两个有序的数组8.两数之和—输入有序数组9...
    99+
    2022-11-13
  • SpringCloud Feign超详细讲解
    目录一、什么是Feign二、Feign能干什么三、Feign的使用步骤1、新建一个module2、配置Pom.xml3、配置applicatin.yaml4、配置configBean...
    99+
    2022-11-13
    SpringCloud Feign原理 SpringCloud Feign使用
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作