【问题标题】:Why is NSMaximumStringLength not INT_MAX为什么 NSMaximumStringLength 不是 INT_MAX
【发布时间】:2014-07-14 18:30:17
【问题描述】:

在阅读 NSString 头文件时,我看到了以下内容。

#define NSMaximumStringLength (INT_MAX-1)

为什么最大字符串长度比INT_MAX短一?这是为了适应空终止符(\0)吗?相关文章can be found here

【问题讨论】:

  • 为什么有人关心它的价值...
  • 这只是信息和用于我的教育目的。 @BryanChen

标签: objective-c nsstring int max


【解决方案1】:

假设:

这是为了容纳NULL char:\0

文档:

在 Apple 文档中找到 hereNSMaximumStringLength

NSMaximumStringLength
DECLARED IN foundation/NSString.h

SYNOPSIS    NSMaximumStringLength
DESCRIPTION NSMaximumStringLength is the greatest possible length for an NSString.

NSString 只是一个“Unicode 字符数组”-Source

NSString 在运行时具体化为__NSCFString或在编译期间具体化为__NSCFConstantString-Source

  • __NSCFString :可能类似于 __NSCFConstantString(参见下面的内存调查)。

  • __NSCFConstantString:使用 char 数组分配 (const char *cStr) - Source


NSString 的内存调查:

代码

NSString *s1 = @"test";

在 LLDB 运行时中断:

类型:

expr [s1 fileSystemRepresentation]

输出:

$0 = 0x0b92bf70 "test" // Essential memory location and content.

在 LLDB 中查看内存类型:

memory read 0x0b92bf70

输出:

0x0b92bf70: 74 65 73 74 00 00 00 00 00 00 00 00 00 00 00 00  test............
0x0b92bf80: 7c 38 d4 02 72 a2 1b 03 f2 e6 1b 03 71 c5 4a 00  |8..r.......q.J.

*注意最后一个字符 t 之后的空终止。

NULL 终止的测试假设:

在之前的代码中添加了char*

NSString *s1 = @"test";
char *p = (char*)[s1 cString];

使用 LLDB 分解代码并输入:

expr p[4] = '\1' // Removing NULL char.

现在如果我们用命令打印 NSString:

expr s1

输出:

(NSString *) $0 = 0x002f1534 @"test
Avg Draw Time: %g"

注意 't' 之后的垃圾,“Avg Draw Time: %g”(又名缓冲区过度读取)。

结论

通过推断,我们可以观察到 NSMaximumStringLength 定义中有 1 byte 留给 NULL 字符来确定内存中字符串的结尾。

【讨论】:

  • 感谢您的持续研究。 +1
  • fileSystemRepresentation 不返回“基本内存位置和内容”。它返回一个“适合与文件系统调用一起使用的格式和编码的 C 字符串”。这与用于 NSString 的内部存储无关。
  • @MartinR:我使用该地址删除 NULL 字符并修改了修改“内部存储”的 NSString。
  • 出色的调查。接受的答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-04
  • 2014-11-18
  • 1970-01-01
  • 1970-01-01
  • 2021-10-20
  • 1970-01-01
相关资源
最近更新 更多