【问题标题】: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 对象。

          【讨论】:

            猜你喜欢
            • 2017-06-15
            • 1970-01-01
            • 2021-11-15
            • 1970-01-01
            • 2012-03-27
            • 2013-09-26
            • 2022-01-16
            • 2021-12-16
            • 1970-01-01
            相关资源
            最近更新 更多