-[NSString dataUsingEncoding:] 在 iOS 9 中的字符串末尾给出垃圾,而不是 iOS 8

-[NSString dataUsingEncoding:] gives garbage at end of string in iOS 9, not iOS 8

下面的代码 运行 在 iOS 8 上很好,但是当 运行 在 iOS 9.0.2 上时,我得到一些奇怪的结果:

NSString * input = @"Hi there";
NSData * data = [input dataUsingEncoding:NSASCIIStringEncoding];
Byte *byteData = (Byte*)malloc(data.length);
memcpy(byteData, [data bytes], data.length);

NSString * result = [NSString stringWithCString:(const char*)byteData encoding:NSASCIIStringEncoding];
NSLog(@"Result: %@", result);

iOS 8.4 (iPhone 6 加) byteDataHi there

iOS 9.0.2 (iPhone 6S) byteDataHi there\xb6<M\x13

在 iOS 9 上,我在字符串末尾遇到了一堆垃圾。

这感觉像是一个 32 位与 64 位的问题,因为它看起来像 iOS9 字节数据长度是原来的两倍?

Apple 在此处将其 table 从 32 位更改为 64 位: https://developer.apple.com/library/ios/documentation/General/Conceptual/CocoaTouch64BitGuide/Major64-BitChanges/Major64-BitChanges.html

data.length 是一个 unsigned long long。这会在调用 malloc 时返回不同的长度吗?上面的代码 returns 8 for data.length when 运行 on each version of iOS.

这感觉很奇怪,我 运行 无法从中攻击它。希望外面的人能够阐明这一点。

谢谢!

更新

我可以使用

修复它
NSString * result = [[NSString alloc] initWithBytes:byteData length:data.length encoding:NSASCIIStringEncoding];

但我仍然想知道为什么我在

的两个 iOS 版本上得到不同的结果
NSString * result = [NSString stringWithCString:(const char*)byteData encoding:NSASCIIStringEncoding];

“C 字符串”以 NUL 字节结尾。由于您使用 dataUsingEncoding: 创建了 data,因此 data 不包含 C 字符串。

由于 stringWithCString:encoding: 正在读取有效内存之外的内容(寻找 NUL 终止符),因此行为未定义,因此可以随时更改。

使用cStringUsingEncoding:创建data,你会得到你需要的NUL终止符。