1

假设我有一些这样的字符串:

NSString *someString = @"123";

然后,我将此字符串转换为 NSData 的实例,如下所示:

NSData *someData = [NSData dataWithBytes:[someString UTF8String] length:[someString length]];

据我了解, NSData 本质上只是一个无编码的比特流。我的问题是:NSData 是否通过检查长度参数的值来确定每个 UTF8String 中有多少位?换句话说,[someString UTF8String] 返回一个包含字符“123”的 C 字符串,而 [someString length] 返回整数 3。NSData 是否理解每个字符必须由 8 位组成?我完全错过了重点吗?

谢谢你。

4

2 回答 2

3

length返回字符串的长度,如“Unicode 字符数”,它不返回其后备存储中的字节数。

要将 NSString 转换为 NSData ,您必须使用以下内容:

NSString *someString = @"123";
NSData *someData = [someString dataUsingEncoding:NSUTF8StringEncoding];

你所做的,适用于仅包含 ASCII 的 UTF8,因为即使在 UTF8 中,ASCII 字符也只占用 1 个字节。巧合的是,字符串的“逻辑”长度与其后备存储的大小相匹配。

尝试使用包含 ASCII 范围之外的字符的字符串,您将看到不同的结果:

NSString *asciiString = @"123";
NSLog(@"\"%@\" - Length: %ld", asciiString, (long)[asciiString length]);
NSData *asciiData = [asciiString dataUsingEncoding:NSUTF8StringEncoding];
NSLog(@"Data length: %ld", [asciiData length]);

NSString *utf8String = @"";
NSLog(@"\"%@\" - Length: %ld", utf8String, (long)[utf8String length]);
NSData *utf8Data = [utf8String dataUsingEncoding:NSUTF8StringEncoding];
NSLog(@"Data length: %ld", [utf8Data length]);

utf8String = @"oö";
NSLog(@"\"%@\" - Length: %ld", utf8String, (long)[utf8String length]);
utf8Data = [utf8String dataUsingEncoding:NSUTF8StringEncoding];
NSLog(@"Data length: %ld", [utf8Data length]);

产量:

"123" - Length: 3
Data length: 3
"" - Length: 2
Data length: 4
"oö" - Length: 2
Data length: 3
于 2013-11-08T07:15:40.733 回答
3

不。

+ (id)dataWithBytes:(const void *)bytes length:(NSUInteger)length

这个方法只需要 2 个参数:指向内存中字节流的 void 指针,以及应该从这个字节流中将多少个字节流带入 NSData 对象的长度。与其他任何方法一样,此方法没有线索,也不关心您是如何获得此字节流的,当然也不知道有关 UTF8String 的任何信息,它只关心数据类型,它们与方法签名匹配。

正如 Matthias 解释的那样,您关于如何确定字符串长度的想法也是错误的。为此使用 strlen C 函数。此函数检查字符串终止空字符 \0。

于 2013-11-08T07:44:03.367 回答