【问题标题】:Do we have to set all properties to nil in -init or is this happening automatically?我们必须在 -init 中将所有属性设置为 nil 还是自动发生?
【发布时间】:2013-05-20 06:17:46
【问题描述】:

我一直相信运行时会在创建对象时自动将所有属性初始化为 nil。

但 App Store 的发布版本与开发期间的调试版本不同。我听说 Xcode 使用各种安全检查机制围绕变量和属性创建了更稳定的调试版本,这些机制可以防止崩溃但会使代码膨胀。

当您为分发而构建时,神话也是如此,编译器优化会去除这些“不必要的”调试代码以使代码更快。

我已经遇到过在发布版本中突然发生的神秘错误。 但现在一位开发人员也告诉我:在发布版本中,运行时不会将属性设置为 nil。它们未初始化。它们的价值是垃圾内存,除非您手动执行。所以!foobar 是不安全的,除非你用 nil 初始化属性。

到目前为止,除非我设置对象,否则我的所有应用程序始终假定属性为 nil。

这是正确的,还是在我们创建对象时运行时仍会将我们的属性初始化为 nil?

【问题讨论】:

  • 据我所知,Objective-C 对象中的所有实例变量在分配对象时都设置为零/nil。仅在调试模式下执行此操作是非常愚蠢的(虽然 Cocoa 设计人员做了一些愚蠢的事情,但我从未见过如此愚蠢的事情)。
  • 虽然有时将init 中的实例变量归零/为零并不是一个愚蠢的想法。您可能会这样做,例如,当您有一堆东西要初始化时,其中大部分都被初始化为非零值。作为文档,您可以继续并将其余部分归零,按照声明的顺序放置初始化 - 成本很小,它有助于确保您已经涵盖了所有内容。 (当然,您也可以添加初始化语句并将其注释掉,或者只是添加该变量自动初始化的注释——这取决于您选择的样式。)

标签: ios objective-c memory-management properties


【解决方案1】:

有问题的开发者错了 你应该接受他们给你的任何其他“建议”作为高度怀疑。

所有实例变量,包括那些由@property 合成的变量,在Objective-C 运行时分配时将始终归零。自语言诞生以来,这就是 Objective-C 运行时的定义和记录的行为。

静态变量也将始终初始化为零/nil/NULL。局部变量在手动保留释放下会被取消初始化,在使用 ARC 时会被初始化为 0/nil/NULL。

DEBUG 和 RELEASE 构建之间有两个主要区别:

  • 链接器将删除所有调试符号。这使得代码更难调试,但可执行文件要小得多。

  • 优化器将针对代码大小和速度进行优化。

正是第二个因素导致了 DEBUG 和 RELEASE 之间的“神秘”行为变化。优化器将根据需要重新使用堆栈空间并重新排序代码中的操作(可以重新排序;例如,方法调用不能)以使代码更快更小。这往往会发现 DEBUG 构建中存在的错误,但不会因为编译器没有在堆栈上移动东西而被触发。

【讨论】:

【解决方案2】:

假设nil,你会没事的。

编译器真的在发布版本中没有做任何不同的事情 - 我认为它去除了调试内容(NSLog、断点处理程序、异常暂停等) .

【讨论】:

  • NSLogs 和异常不会被剥离,并且编译器在 RELEASE 构建期间的行为非常不同。所有 ivars 都将被清零,无论它们是如何声明的。
  • 实际上并不是将 ivars 设置为 0 的编译器——而是运行时,特别是 class_createInstance(),由 alloc/allocWithZone: 调用。
猜你喜欢
  • 2012-06-15
  • 1970-01-01
  • 2019-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多