【问题标题】:Memory Allocation of variables & constants outside Swift classesSwift 类之外的变量和常量的内存分配
【发布时间】:2016-08-19 16:53:30
【问题描述】:

我已经看到了在类外部创建的变量和常量的代码示例,以作为避免硬编码的一种方式。 它们在内存分配方面是一个好习惯吗? 例如:

private let cellId = "myCellId"

class ViewController : UIViewController {

    ...
    let cell = tableView.dequeueReusableCellWithIdentifier(cellId)
    ...
}

这些常量/变量何时在 iOS 应用程序中分配/释放?

【问题讨论】:

  • Abizern 回答了第一个问题。当它们被释放时,答案是它们永远不会被释放。因此,您可能只想在 (a) 分配的对象不太大的情况下使用此构造(即,即使需要它的对象不再存在,您也不介意保留它); (b) 你以后可能会再次需要它。

标签: ios swift memory-management


【解决方案1】:

像这样的顶级全局变量是延迟初始化的。此外,它们在 dispatch_once 中隐式分配,因此它们是线程安全的。

全局变量的惰性初始化器(也适用于结构和枚举的静态成员)在第一次访问全局时运行,并作为 dispatch_once 启动以确保初始化是原子的。这为在代码中使用 dispatch_once 提供了一种很酷的方式:只需使用初始化程序声明一个全局变量并将其标记为私有。

参考:Swift blog

【讨论】:

    【解决方案2】:

    总的来说,阿比伦是正确的。但是,常量字符串有点特殊。他们永远不会被分配。它们存在于您的二进制映像中,该映像是内存映射的,几乎与您可以获得的“免费”一样接近。由于结构正是它们的内容(即结构上没有标头),因此您的字符串在二进制文件中正好花费 9 个字节(字符加​​上尾随的 0)。它永远不会被分配;就是这样。

    由于cellIdlet,编译器可以用保存数据的二进制文件中的实际内存位置替换对它的引用。甚至不需要cellId 本身的指针。

    【讨论】:

    • 感谢您的回答!这意味着我可以很好地将这种技术用于字符串和数字(​​以及其他值类型)来对整个类文件中的常量进行软编码?您有任何参考资料或博客文章详细说明这一点吗?再次感谢!
    • 不是所有的值类型;但至少是字符串和数字;其他一些也可能是特殊情况。编译器需要知道如何在编译时构造它们。我不确定这是如何记录的。这不是 Swift 的语言要求;这就是它的实现方式,并且基于 C 编译器几十年来如何做到这一点。有点像如果你写“x = 1 + 2”,任何现代编译语言的每个编译器都会存储“x = 3”,但我不知道任何需要它的语言规范。
    • 对,有道理!我认为这可能也适用于 Core Graphics 框架的常量,例如 CGFloat 甚至像 CGRect 这样的结构类型,因为它们由简单的数字数据类型组成。
    猜你喜欢
    • 1970-01-01
    • 2015-06-04
    • 2013-05-13
    • 2011-12-19
    • 2011-11-12
    • 2014-08-27
    • 2021-02-19
    • 1970-01-01
    相关资源
    最近更新 更多