NSString踩坑

NSString是最最常用的类之一。但是时不时还是会被NSString坑到。在这里记录两个我遇到的坑。

length

length方法每天用来用去竟然也有坑!!?不信的话看看以下的代码。

NSString *str = @"您来啦啦";
NSData *data = [NSData dataWithBytes:str.UTF8String length:[str length]];
NSString *str2 = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@", str2);

最后输出什么呢?当然不是您来啦啦,而是(null)。str2为nil。原因是str中包含中文,UTF8编码下,中文占多个byte。

NSLog(@"lenght: %zd", [str length]); // lenght: 4
NSLog(@"length of UTF8String: %ld", strlen(str.UTF8String)); // length of UTF8String: 12

正确的写法如下:

NSString *str = @"您来啦啦";
NSData *data = [NSData dataWithBytes:str.UTF8String length:[str lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];
NSString *str2 = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@", str2); // 您来啦啦

getCString:maxLength:encoding:

如果从方法的名字上理解,是将NSString的UTF8String拷贝到bytes中,长度不超过maxLength,如果UTF8String的长度大于maxLength,则取前面的maxLength长度的串。但是这么理解,只理解对了一半。

如果maxLength < lengthOfBytesUsingEncoding获取的长度,方法不会将数据拷贝到bytes中,返回NO

char cstr[5] = {'a', 'b', 'c', 'd', '\0'};
BOOL ret = [@"uvwxyz" getCString:cstr maxLength:sizeof(cstr) encoding:NSUTF8StringEncoding];
NSLog(@"ret:%@ %s", ret ? @"YES" : @"NO", cstr);
ret = [@"xyz" getCString:cstr maxLength:sizeof(cstr) encoding:NSUTF8StringEncoding];
NSLog(@"ret:%@ %s", ret ? @"YES" : @"NO", cstr);

输出如下:

ret:NO abcd
ret:YES xyz

结果显而易见。不再赘述。

您的支持将鼓励我继续创作。