Как извлечь UnsafePointer <CGFloat>из UnsafePointer <CGPoint>- Swift - PullRequest
0 голосов
/ 14 апреля 2020

Я играю с изучением указателей в Swift.

Например, этот код начинается с массива CGPoint, создает UnsafePointer и затем извлекает все значения x в CGFloat array:

import Foundation

let points = [CGPoint(x:1.2, y:3.33), CGPoint(x:1.5, y:1.21), CGPoint(x:1.48, y:3.97)]
print(points)

let ptr = UnsafePointer(points)
print(ptr)

func xValues(buffer: UnsafePointer<CGPoint>, count: Int) -> [CGFloat]? {
    return UnsafeBufferPointer(start: buffer, count: count).map { $0.x }
}

let x = xValues(buffer: ptr, count: points.count)
print(x)

И ожидаемый результат:

[Foundation.CGPoint(x: 1.2, y: 3.33), Foundation.CGPoint(x: 1.5, y: 1.21), Foundation.CGPoint(x: 1.48, y: 3.97)]
0x0000556d6b818aa0
Optional([1.2, 1.5, 1.48])

Теперь я хотел бы, чтобы функция xValues ​​возвращала UnsafePointer<CGFloat> напрямую, вместо того, чтобы проходить через [CGFloat] .

Как мне это сделать, возможно ли это?

1 Ответ

2 голосов
/ 14 апреля 2020

Выводить указатели подобным образом небезопасно. Как упоминалось в комментариях, вы должны использовать метод withUnsafeBufferPointer для доступа к базовому буферу:

let points = [
  CGPoint(x:1.2, y:3.33), 
  CGPoint(x:1.5, y:1.21), 
  CGPoint(x:1.48, y:3.97)
]

let xValues = points.withUnsafeBufferPointer { buffer in
  return buffer.map { $0.x }
}

Если вам нужен указатель на массив CGFloat, просто используйте тот же метод, что и выше:

xValues.withUnsafeBufferPointer { buffer in 
  // Do things with UnsafeBufferPointer<CGFloat>
}

Хороший учебник по Swift Pointer здесь .


Edit

Вот рабочий пример:

let points = [
    CGPoint(x:1.2, y:3.33), 
    CGPoint(x:1.5, y:1.21),
    CGPoint(x:1.48, y:3.97)
]

// Create, init and defer dealoc
let ptr = UnsafeMutablePointer<CGFloat>.allocate(capacity: points.count)
ptr.initialize(repeating: 0.0, count: points.count)
defer {
    ptr.deallocate()
}

// Populate pointer
points.withUnsafeBufferPointer { buffer in
    for i in 0..<buffer.count {
        ptr.advanced(by: i).pointee = buffer[i].x
    }
}

// Do things with UnsafeMutablePointer<CGFloat>, for instance:
let buffer = UnsafeBufferPointer(start: ptr, count: points.count)

for (index, value) in buffer.enumerated() {
    print("index: \(index), value: \(value)")
}
...