【问题标题】:Why does declaring pointer makes it contents nil? [duplicate]为什么声明指针使其内容为零? [复制]
【发布时间】:2011-09-23 12:43:20
【问题描述】:
可能重复:
Declared but unset variable evaluates as true?
为什么这段代码可以在 Mac OS 上运行
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString *str;
NSLog(@"%@", [str length]);
NSLog(@"Hello, World!");
[pool drain];
return 0;
}
控制台输出是
2011-09-23 15:37:17.481 Untitled1[80021:903] (null)
2011-09-23 15:37:17.495 Untitled1[80021:903] Hello, World!
但在 iPhone 上崩溃?
【问题讨论】:
标签:
iphone
objective-c
macos
pointers
null
【解决方案1】:
两个错误。
首先,声明指针 str,不要设置它的值并在 NSLog 中使用它。
其次,您使用格式 %@,但提供整数值 ([str length]),结果未定义。这就是为什么在模拟器上它打印 null,但在设备上崩溃。
【解决方案2】:
你很幸运。局部变量未初始化,可以包含任何内容。很可能在 OS X 上,str 包含 0(又名 nil),将 -length 发送到 nil 返回 0。然后您将长度(即 NSInteger)视为 NSLog 的指针。
如果长度为 0,如果格式说明符为 %@,NSLog 会将其视为 nil 指针并打印 (null)。
如果str 有一个随机的非零值,当你发送长度时你的程序会崩溃,或者如果它奇迹般地工作并返回非零长度,它可能会在尝试将其视为 NSLog 中的对象指针时崩溃
【解决方案3】:
该值永远不会被初始化(或设置)。它可以是任何随机值。在调试时,它可能是零初始化的。
在这种情况下,您应该期待崩溃(或某些 UB)。所以...打开您的编译器和静态分析器警告,修复问题,并始终初始化您的值。
【解决方案4】:
试试这个。
NSString *str=@"";
NSLog(@"%d", [str length]);
【解决方案5】:
看,
您只能在 nil 对象上调用 release 方法。除了 release 方法,我们不能在 nil 上调用任何方法。
这里你在一个指向 nil 的对象上调用一个方法(长度),在这种情况下,它通常应该在发送长度消息之前指向 nsstring 对象。