我对NSString内部问题有疑问。 我想检查一个字符串长度,基本上我想知道NSString每次知道它的长度/数量/计数和数量。缓存结果。
我应该存储它的长度并每次计算或调用长度方法吗?
要测试一个字符串,我可以测试nil或者询问它的长度。
if (str != nil) {
// compute
}
if ([str length]) {
// compute
}
哪一个最快? 哪一个内存效率更高?
由于
答案 0 :(得分:6)
检查nil
(“无对象”)绝对不与向(NSString)对象发送length
消息相同。只有一个条件检查有效,以测试“空”字符串。 (“空”字符串是一个对象,因此不是nil
。)
更大的问题是:NSString存储长度还是哨点终止(如“普通c字符串”)? NSString将长度存储为内部属性,因此length
为O(1)操作。
快乐的编码。
答案 1 :(得分:6)
以下是CFStringGetLength的工作原理:
(来自http://opensource.apple.com/source/CF/CF-550.43/CFString.c)
/* Returns length; use __CFStrLength2 if contents buffer pointer has already been computed.
*/
CF_INLINE CFIndex __CFStrLength(CFStringRef str) {
if (__CFStrHasExplicitLength(str)) {
if (__CFStrIsInline(str)) {
return str->variants.inline1.length;
} else {
return str->variants.notInlineImmutable1.length;
}
} else {
return (CFIndex)(*((uint8_t *)__CFStrContents(str)));
}
}
所有情况都应该为O(1)。
答案 2 :(得分:2)
两个 - 测试nil的NSString指针并测试NSString的长度 - 在任何方面都不相同。可以存在长度为零的NSString对象,并且指向它的指针不会等于nil。
据我所知(我发现自己错了很惊讶),NSString的长度作为有效引用的属性存储在对象中。缓存长度通常是不必要的复杂性。
答案 3 :(得分:1)
NSString是不可变类,所以长度始终保持不变。
答案 4 :(得分:1)
附录:针对[字符串长度]的测试在两种情况下评估为0 / nil / NO(字符串为nil,字符串为零长度)。