【问题标题】:iOS - NSString definition / initialization. 64bit vs 32bitiOS - NSString 定义/初始化。 64 位与 32 位
【发布时间】:2015-12-04 23:40:10
【问题描述】:

我遇到了一个非常奇怪的问题。我在定义 NSString 对象时犯了一个错误。这是一个明显的错误。但奇怪的是,它在某些 iOS 设备上运行良好,而在其他设备上却导致崩溃。

我已经修复了这个错误,但我仍然不知道它为什么会起作用。

如果有人能帮助我理解这一点,将不胜感激。

谢谢!

错误代码:

NSString *language2 = [[NSLocale preferredLanguages] objectAtIndex:0];

NSString *language = [language substringToIndex:2];
NSLog(@"language = %@", language);

如你所见,“NSString *language = [language substringToIndex:2];”被定义为自身的子字符串。

疯狂的是,这在某些设备上有效。我猜这是一个 64/32 位的东西,我只是不明白。

它在旧 iPad 上崩溃。在较新的 iPhone6 上,它可以工作,并且 NSLog 指示“language = en”。

有什么想法吗?

【问题讨论】:

    标签: ios objective-c ios8 ios9


    【解决方案1】:

    如果您启用了 ARC,则所有局部变量将在使用前初始化为 NULL。那么,您是否启用了 ARC?此外,32 位和 64 位目标之间存在一些完全不同的代码生成,包括堆栈的增长方式。可能是您“走运了”,并且由于调用时寄存器溢出,对象引用落入了堆栈上的正确位置。

    如果您想探索更多,请尝试使用 NSLog() 打印对象的地址 (@"%p")。不过,您很可能会导致不同的行为。

    总而言之,您正在玩​​未定义的行为,并且它以未定义的方式正确地表现。 :)

    【讨论】:

    • 谢谢!经过一番观察,似乎我确实“幸运”了 64 位设备没有崩溃,因为内存地址填充了一个先前的值......即使该值不正确,它仍然可以防止导致的对象引用错误在 32 位设备上崩溃。感谢您的洞察力。
    • @mtb 请注意,如果您打开优化器或切换优化级别,行为也可能会发生变化!实际上,我有点惊讶编译器在这种情况下没有发出警告。
    【解决方案2】:

    我不认为这是导致混淆的想法,因为我在不同的设备、真实设备和模拟器设备以及不同的 iOS 版本上尝试了完全相同的代码。只有我得到StackOverExpObjectiveC[] (null)这是实际预期的。如果您可以分享更多您的项目,也许会发现奇怪的东西的基础......

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-18
      • 1970-01-01
      • 2010-09-16
      • 2013-06-21
      • 1970-01-01
      • 1970-01-01
      • 2014-01-04
      • 2011-09-24
      相关资源
      最近更新 更多