Swift Language
(안전하지 않은) 버퍼 포인터
수색…
소개
"버퍼 포인터는 메모리 영역에 대한 하위 수준 액세스에 사용됩니다. 예를 들어, 버퍼 포인터를 사용하여 애플리케이션과 서비스간에 데이터를 효율적으로 처리하고 통신 할 수 있습니다. "
발췌 : Apple Inc. "Swift with Cocoa and Objective-C (Swift 3.1 Edition)."iBooks. https://itun.es/us/utTW7.l
누수 또는 정의되지 않은 동작을 피하기 위해 버퍼 포인터를 통해 작업하는 모든 메모리의 수명주기를 처리해야합니다.
비고
(Unsafe) BufferPointers에 대한 이해를 완성 하기 위해 밀접하게 정렬 된 개념.
- MemoryLayout (형태 의 메모리 레이아웃으로, 사이즈, 보폭 및 정렬을 기술 합니다.)
- 관리되지 않는 개체 참조를 전파하는 형식입니다 .
- UnsafeBufferPointer ( 메모리에 연속적으로 저장된 요소의 버퍼에 대한 비 소유 콜렉션 인터페이스 )
- UnsafeBufferPointerIterator ( UnsafeBufferPointer 또는 UnsafeMutableBufferPointer 인스턴스에 의해 참조되는 버퍼 내의 요소의 반복자 )
- UnsafeMutableBufferPointer ( 메모리에 연속적으로 저장된 변경 가능한 요소의 버퍼에 대한 소유 컬렉션 인터페이스가 아닙니다. )
- UnsafeMutablePointer ( 특정 유형의 데이터에 액세스하고 조작하기위한 포인터 )
- UnsafeMutableRawBufferPointer ( 메모리 영역의 바이트에 대한 변경 불가능한 콜렉션 인터페이스 )
- UnsafeMutableRawBufferPointer . iterator ( raw 버퍼 포인터에 의해 표시되는 바이트의 반복자 )
- UnsafeMutableRawPointer ( 형식화되지 않은 데이터에 액세스하고 조작하기위한 원시 포인터 )
- UnsafePointer ( 특정 유형의 데이터에 액세스하기위한 포인터 )
- UnsafeRawBufferPointer ( 메모리 영역의 바이트에 대한 비 소유 컬렉션 인터페이스. )
- UnsafeRawBufferPointer . iterator ( raw 버퍼 포인터로보고있는 바이트의 반복자 )
- UnsafeRawPointer ( 형식화되지 않은 데이터에 액세스하기위한 원시 포인터 )
(출처 : Swiftdoc.org )
UnsafeMutablePointer
struct UnsafeMutablePointer<Pointee>
특정 유형의 데이터를 액세스하고 조작하기위한 포인터.
UnsafeMutablePointer 형식의 인스턴스를 사용하여 메모리의 특정 형식의 데이터에 액세스합니다. 포인터가 액세스 할 수있는 데이터 유형은 포인터의 Pointee 유형입니다. UnsafeMutablePointer는 자동화 된 메모리 관리 또는 정렬 보장을 제공하지 않습니다. 안전하지 않은 포인터를 통해 작업하는 메모리의 수명주기를 처리하여 누출 또는 정의되지 않은 동작을 방지해야합니다.
수동으로 관리하는 메모리는 유형을 지정하지 않거나 특정 유형에 바인딩 할 수 있습니다. UnsafeMutablePointer 형식을 사용하면 특정 형식에 바인딩 된 메모리를 액세스하고 관리 할 수 있습니다. ( 출처 )
import Foundation
let arr = [1,5,7,8]
let pointer = UnsafeMutablePointer<[Int]>.allocate(capacity: 4)
pointer.initialize(to: arr)
let x = pointer.pointee[3]
print(x)
pointer.deinitialize()
pointer.deallocate(capacity: 4)
class A {
var x: String?
convenience init (_ x: String) {
self.init()
self.x = x
}
func description() -> String {
return x ?? ""
}
}
let arr2 = [A("OK"), A("OK 2")]
let pointer2 = UnsafeMutablePointer<[A]>.allocate(capacity: 2)
pointer2.initialize(to: arr2)
pointer2.pointee
let y = pointer2.pointee[1]
print(y)
pointer2.deinitialize()
pointer2.deallocate(capacity: 2)
원본 소스 에서 Swift 3.0으로 변환
버퍼 포인터의 실제 사용 사례
Swift 라이브러리 메소드에서 안전하지 않은 포인터의 사용을 해체합니다.
public init?(validatingUTF8 cString: UnsafePointer<CChar>)
목적:
주어진 포인터에 의해 참조되는 널 종료 된 UTF-8 데이터를 복사하고 유효성 검사하여 새 문자열을 작성합니다.
이 초기화 프로그램은 잘못 구성된 UTF-8 코드 단위 시퀀스를 복구하려고하지 않습니다. 어떤 것이 있으면 초기화 프로그램의 결과는 nil
입니다. 다음 예제는 두 개의 다른 CChar
배열의 내용에 대한 포인터를 사용하여이 초기화 프로그램을 호출합니다. 첫 번째는 잘 형성된 UTF-8 코드 단위 시퀀스를 사용하고 두 번째 코드는 부적절한 시퀀스를 끝에 붙입니다.
Source , Apple Inc., Swift 3 헤더 파일 (헤더 액세스의 경우 : 놀이터에서 Cmd + Swift 단어 클릭)
import Swift
let validUTF8: [CChar] = [67, 97, 102, -61, -87, 0]
validUTF8.withUnsafeBufferPointer { ptr in
let s = String(validatingUTF8: ptr.baseAddress!)
print(s as Any)
}
// Prints "Optional(Café)"
let invalidUTF8: [CChar] = [67, 97, 102, -61, 0]
invalidUTF8.withUnsafeBufferPointer { ptr in
let s = String(validatingUTF8: ptr.baseAddress!)
print(s as Any)
}
// Prints "nil"
(출처, Apple Inc., 신속한 헤더 파일 예제)