Преобразование Objective-C memcpy в Swift - PullRequest
0 голосов
/ 10 ноября 2018

Мне поручено преобразовать некоторые функции из Objective-C в Swift. Мы используем файл C для передачи файлов на устройство Bluetooth. Вот код Objective-C, который необходимо преобразовать.

Из файла Objective-C:

NSString *room_name = filename;
NSData* bytes = [room_name dataUsingEncoding:NSUTF8StringEncoding];
UInt8 buff_name[bytes.length+1];
memcpy(buff_name, [room_name UTF8String],[room_name lengthOfBytesUsingEncoding:NSUTF8StringEncoding] + 1);

Я застрял на memcpy для Swift и не уверен, что это самый безопасный метод для того, что мы пытаемся сделать. Спасибо.

1 Ответ

0 голосов
/ 10 ноября 2018

Мои соболезнования, так как код, который вы дали, немного беспорядок. Сначала он делает NSData из room_name, конвертируя строку в UTF-8 в процессе, но затем он не использует этот NSData для чего-либо другого, кроме определения размера буфера, а затем преобразует строку в UTF-8 снова и копирует ее в новый буфер. Это гораздо более неэффективно, как с вычислительной , так и с точки зрения читабельности, чем должно быть.

Если бы мы оставили это в Objective-C, мы бы уже хотели очистить код. Однако в Swift мы можем сделать это еще чище, потому что String имеет действительно хороший и простой способ получить указатель на представление строки UTF-8:

filename.withCString { ptr in
    // call whatever C-based functions expect a `const char *` pointer here
}

Обратите внимание, что указатель, который вы здесь получаете, является неизменным. Если функции C, которые вы вызываете, ожидают, что смогут изменить буфер, вы вместо этого захотите сделать копию. Есть несколько способов сделать это, но самый простой, вероятно, просто:

guard var data = filename.data(using: .utf8) else {
    // handle this error somehow
}

data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<Int8>) in
    // call whatever C-based functions expect a `char *` pointer here
    // (if you need `unsigned char *`, use `UInt8` instead of `Int8`)
}
...