Как NSData(bytes:length:) преобразует [Byte] в UnsafePointer‹Void› в Swift?

Играя с необработанными данными в Swift, я наткнулся на кое-что, чего не понимаю.
NSData имеет конструктор:

init(bytes: UnsafePointer<Void>, length: Int)

где первый параметр bytes явно имеет тип UnsafePointer.
Однако, если я передам объект [Byte] в этот конструктор, не только компилятор не жалуется, но работает нормально.
Но если я попытаюсь преобразовать [Byte] в UnsafePointer, у меня ничего не получится.
Как это работает ?

Например (вы можете попробовать это в Playgrounds):

let buffer: [Byte] = [0x00, 0xff]
let data = NSData(bytes: buffer, length: buffer.count) // no error
data.description

var pointer: UnsafePointer<Void>
// comment this line to avoid compiler error
pointer = buffer // error

я знаю, что могу сделать

UnsafePointer<Void>(buffer)

но мой вопрос в том, что неявно делает конструктор NSData, что мне не нужно этого делать.


person Bartek Chlebek    schedule 25.09.2014    source источник


Ответы (1)


Swift сопоставляет свои собственные типы с указателями C, когда вы вызываете функцию C, которая их требует. У Apple есть небольшая документация по этому взаимодействию: Взаимодействие с C API.

Короче говоря, когда вы вызываете функцию, которая принимает UnsafePointer<Type>, она может принимать nil, переменную inout этого типа, массив этого типа (то есть [Type], что вы используете) или одну из общих функций Swift. типы указателей. Функция, принимающая UnsafePointer<Void>, может принимать любой из них без каких-либо ограничений на тип, поэтому вам нужно прочитать документацию функции, чтобы увидеть, что она ожидает/вернет.

person Nate Cook    schedule 25.09.2014
comment
Это также упоминается в этой статье блога (developer.apple.com/swift/blog/ ?id=6) в разделе Указатели как параметры массива - person newacct; 26.09.2014