Мое приложение использует несколько сложную неинтегрируемую структуру данных, которая закодирована в двоичном файле. Мне нужно иметь доступ к нему на уровне байта, избегая копирования. Обычно я должен использовать арифметику указателей C или С++ и приемы типов, чтобы получать и интерпретировать значения исходного байта. Я хотел бы сделать то же самое с Swift.
Я обнаружил, что следующие работы:
class RawData {
var data: NSData!
init(rawData: NSData) {
data = rawData
}
func read<T>(byteLocation: Int) -> T {
let bytes = data.subdataWithRange(NSMakeRange(byteLocation, sizeof(T))).bytes
return UnsafePointer<T>(bytes).memory
}
func example_ReadAnIntAtByteLocation5() -> Int {
return read(5) as Int
}
}
Однако я не уверен, насколько он эффективен. Делать data.subdataWithRange
и NSMakeRange
распределять объекты каждый раз, когда я их вызываю, или они просто синтаксический сахар для работы с указателями?
Есть ли лучший способ сделать это в Swift?
EDIT:
Я создал небольшой класс Objective-C, который просто инкапсулирует функцию для смещения указателя на заданное количество байтов:
@implementation RawDataOffsetPointer
inline void* offsetPointer(void* ptr, int bytes){
return (char*)ptr + bytes;
}
@end
Если я включу этот класс в заголовок моста, то я могу изменить свой метод read
на
func read<T>(byteLocation: Int) -> T {
let ptr = offsetPointer(data.bytes, CInt(byteLocation))
return UnsafePointer<T>(ptr).memory
}
который не будет копировать данные из моего буфера или выделять другие объекты.
Однако было бы неплохо сделать некоторую арифметику указателя из Swift, если это было возможно.