你好哈哈哈 發表於 2022-8-2 09:51:47

Swift超详细讲解指针

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>Swift指针Unsafe Pointer</li><li>对照Objective-C</li><li>例子</li></ul></div><p class="maodian"></p><h2>Swift指针Unsafe Pointer</h2>
<p>如果不是只读,可以修改 ( 写入 ),就加一个 Mutable,</p>
<p>如果没有具体的类型( 通过泛型的方式 ),就加一个 Raw,</p>
<p>如果不是一个单独的对象 ( 指向集合类型 ),就加上 buffer.</p>
<blockquote><p>Unsafe [ Mutable ] [ Raw ] [ Buffer ] Pointer [ ]</p></blockquote>
<p>苹果没有编译保护的 [ 可变的 ] [没有类型的] [ 是集合的 ] 指针 [&lt; 具体的类型 &gt;]</p>
<p class="maodian"></p><h2>对照Objective-C</h2>
<ul><li>swift 的 <code>unsafeMutablePointer&lt;T&gt;</code>: OC 的 T *</li><li>swift 的 <code>unsafePointer&lt;T&gt;</code>: OC 的 const T *</li><li>swift 的 unsafeRawPointer: OC 的 const void *</li><li>swift 的 unsafeMutableRawPointer: OC 的 void *</li></ul>
<p class="maodian"></p><h2>例子</h2>
<p>例子 1, 无类型的指针</p>
<div class="jb51code"><pre class="brush:cpp;">let count = 2
let stride = MemoryLayout&lt;Int&gt;.stride
let alignment = MemoryLayout&lt;Int&gt;.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)")
}
}</pre></div>
<p>2, 具体类型的指针</p>
<p>具体类型的指针,可以通过指针的 <code>pointee</code> 属性,方便的操作 load 和 store</p>
<div class="jb51code"><pre class="brush:cpp;">let count = 2
let stride = MemoryLayout&lt;Int&gt;.stride
let alignment = MemoryLayout&lt;Int&gt;.alignment
let byteCount = stride * count
do {
print("Typed pointers")
let pointer = UnsafeMutablePointer&lt;Int&gt;.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)")
}
}</pre></div>
<p>例子 3: 通过绑定内存,来做指针的转化</p>
<p><code>bindMemory</code></p>
<div class="jb51code"><pre class="brush:cpp;">let count = 2
let stride = MemoryLayout&lt;Int&gt;.stride
let alignment = MemoryLayout&lt;Int&gt;.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)")
}
}</pre></div>
<p>例子 4, 查看指针的字节</p>
<div class="jb51code"><pre class="brush:cpp;">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: &amp;one) { bytes in
    for byte in bytes {
      print(byte)
    }
}
}</pre></div>
<p>例子 4.1, 指针的字节, 算 check sum</p>
<div class="jb51code"><pre class="brush:cpp;">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: &amp;one) { (bytes) -&gt; UInt32 in
    return ~bytes.reduce(UInt32(0)) { $0 + numericCast($1) }
}
print("checksum", checksum) //checksum 4294967269
}</pre></div>
<p>checeSum 的使用,分为 checeSum 的计算与校验</p>
<p>本文简单描述 checeSum 的计算</p>
<p>数据块,分为 n 个包, size 相同</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202208/2022080209395811.png" /></p>
<p>拿包的字节,计算 checkSum, checkSum 的大小限制在包的 size</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202208/2022080209395812.png" /></p>
<p>例子 5, 获取变量的指针</p>
<div class="jb51code"><pre class="brush:cpp;">var cat = "fly"
// 返回的是,闭包中的参数
// withUnsafePointer , 把闭包里面的结果,rethrow 出去 ( 相当于 return 出来 )
let warrior = withUnsafePointer(to: &amp;cat, { $0 })
print(warrior.pointee)</pre></div>
<p>例子 6, 指向多个元素的指针</p>
<div class="jb51code"><pre class="brush:cpp;">struct Cat{
    var habit = "eat"
    var paws = 6
    var name = "load"
}
let ptr = UnsafeMutablePointer&lt;Cat&gt;.allocate(capacity: 2) // 指向两个 Cat 结构体
ptr.initialize(repeating: Cat(), count: 2)
defer{
    ptr.deinitialize(count: 2)
    ptr.deallocate()
}
var one = Cat()
one.paws = 8
ptr = one
// 以下两个等价
print(ptr)
print(ptr.pointee)
// 下面 3 个等价
print(ptr)
print((ptr + 1).pointee)
print(ptr.successor().pointee)</pre></div>
<p>例子 7: 元素组合的探索</p>
<div class="jb51code"><pre class="brush:cpp;">var pair = (66, 666)
func test(ptr: UnsafePointer&lt;Int&gt;){
    print(ptr.pointee)
    print(ptr.successor().pointee)
}
withUnsafePointer(to: &amp;pair) { (tuplePtr: UnsafePointer&lt;(Int, Int)&gt;) in
    // 假定内存绑定,不需要经过内存检查
    test(ptr: UnsafeRawPointer(tuplePtr).assumingMemoryBound(to:Int.self))
}</pre></div>
<p>参考了 Unsafe Swift: Using Pointers and Interacting With C</p>
<p>到此这篇关于Swift超详细讲解指针的文章就介绍到这了,更多相关Swift指针内容请搜索琼殿技术社区以前的文章或继续浏览下面的相关文章希望大家以后多多支持琼殿技术社区!</p>
                           
                            <div class="art_xg">
                              <b>您可能感兴趣的文章:</b><ul><li>Swift 指针底层探索分析</li><li>详解Swift的内存管理</li><li>深入探究Swift枚举关联值的内存</li><li>swift指针及内存管理内存绑定实例详解</li></ul>
                            </div>

                        </div>
                        <!--endmain-->
頁: [1]
查看完整版本: Swift超详细讲解指针