【问题标题】:NSString internals - how does length works?NSString 内部结构 - 长度如何工作?
【发布时间】:2011-07-08 20:41:16
【问题描述】:

我有一个关于 NSString 内部结构的问题。 我想检查一个字符串长度,基本上我想知道一个 NSString 是否知道它的长度/每次计数/计数并缓存结果。

我应该存储它的长度并计算还是每次调用长度方法?

要测试一个字符串,我可以针对 nil 进行测试或询问它的长度。

if (str != nil) {
  // compute
}

if ([str length]) {
  // compute
}

哪个最快? 哪个内存效率更高?

谢谢

【问题讨论】:

    标签: iphone objective-c cocoa-touch performance cocoa


    【解决方案1】:

    检查nil(“无对象”)绝对与将length 消息发送到(NSString)对象相同。只有一个条件检查对测试“空”字符串有效。 (“空”字符串是一个对象,因此不是nil。)

    更大的问题是:NSString 是存储长度还是哨兵终止的(如“普通 c 字符串”)? NSString 将长度存储为内部属性,因此 length 是 O(1) 操作。

    编码愉快。

    【讨论】:

      【解决方案2】:

      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)。

      【讨论】:

        【解决方案3】:

        这两者——测试一个 NSString 指针是否为 nil 和测试一个 NSString 的长度——在任何方面都不是等价的。可以存在长度为零的 NSString 对象,指向它的指针不会比较等于 nil。

        据我所知(如果我发现自己错了,我会很惊讶),NSString 的长度作为有效引用的属性存储在对象中。缓存长度通常是不必要的复杂性。

        【讨论】:

          【解决方案4】:

          NSString 是不可变类,所以长度始终保持不变。

          【讨论】:

          • NSMutableString 是否也将其长度存储为 O(1) 属性?
          • 我假设(因为它更有效)但我不确定。
          【解决方案5】:

          附录:针对 [字符串长度] 的测试在两种情况下的计算结果均为 0/nil/NO(字符串为 nil 且字符串长度为零)。

          【讨论】:

          • 这提醒了我:我一直想知道,来自 Java 和 Smalltalk 的背景,nil 到底是什么。它是一个特殊的类(就像在 Smalltalk 中一样,没有原语,所有东西(!)都是一个对象),还是只是一个等于 int 0 的常量?我想由于 c 根,0、nil、NULL、NO、false 都是一样的 - 0?
          • nilobjc.h 中定义为__DARWIN_NULL,在 中定义为((void *)0)
          • @fzwo nilnull 是表示“无对象”的特殊值。 nil 是各自“无类型”的唯一居民:即使有实现细节泄漏(“0/NULL”),也可以这样认为。也就是说,nil 是一个只能表示一件事的值:“没有对象”。 NULL vs nil 可能很有趣,因为它表明 Objective-C 确实只是 C/C++ 上的一个层 ;-) [我上面所说的依赖于语义的使用。]
          猜你喜欢
          • 2022-01-06
          • 2018-09-07
          • 2018-05-08
          • 1970-01-01
          • 2013-02-22
          • 2019-12-05
          • 2012-01-24
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多