Objective-C中unsigned char*与NSData互相转换的实现方法
问题分析
你提供的代码存在多处错误,无法完成正确的NSData与Byte类型互相转换,具体问题如下:
- NSLog使用
%@格式化符打印unsigned char *类型变量:%@仅适用于打印Objective-C对象,unsigned char *是C语言指针类型,直接使用%@打印会引发崩溃或输出乱码。 - 生成NSData时传入
&dataToByteArray作为参数:该值是字节指针本身的内存地址,并非字节内容的实际存储地址,会导致生成的NSData内容完全错误。 - 长度参数使用
sizeof(dataToByteArray):dataToByteArray是指针类型,在64位系统下sizeof返回值固定为8,和原始NSData的实际字节长度无关,会导致生成的NSData长度错误。
规范实现方案
1. NSData转Byte字节数组
如果你只是临时读取字节内容,不需要长期持有字节数组,可以直接使用NSData的bytes属性,该指针生命周期和原NSData对象绑定,原对象释放后指针会自动失效:
NSData *originalData = [@"测试内容" dataUsingEncoding:NSUTF8StringEncoding]; const unsigned char *bytes = originalData.bytes; // 遍历打印字节内容 for (NSUInteger i = 0; i < originalData.length; i++) { NSLog(@"第%lu个字节:0x%x", (unsigned long)i, bytes[i]); }
如果你需要长期持有字节数组,和原NSData生命周期解耦,需要手动申请内存拷贝内容:
NSData *originalData = [@"测试内容" dataUsingEncoding:NSUTF8StringEncoding]; NSUInteger len = originalData.length; unsigned char *byteArray = (unsigned char *)malloc(len * sizeof(unsigned char)); if (byteArray) { memcpy(byteArray, originalData.bytes, len); // 这里可以对byteArray进行操作 // 用完后必须释放手动申请的内存,避免泄漏 free(byteArray); }
2. Byte字节数组转NSData
转换时需要传入字节数组的首地址和实际长度:
// 示例字节数组 unsigned char testBytes[] = {0xe6, 0xb5, 0x8b, 0xe8, 0xaf, 0x95}; // 对应UTF8编码的"测试"二字 NSUInteger bytesLen = sizeof(testBytes) / sizeof(unsigned char); // 转换为NSData NSData *data = [NSData dataWithBytes:testBytes length:bytesLen]; // 验证转换结果 NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"转换结果:%@", result);
注意事项
- 不要持有
[data bytes]返回的指针太久,原NSData释放后该指针会变成野指针,访问会引发崩溃。 - 手动malloc的字节数组使用完成后必须调用free释放,否则会出现内存泄漏。
内容的提问来源于stack exchange,提问作者Nik Jack
相关产品推荐
相关产品推荐

