【问题标题】:nil in an optional type, what exactly is behind it? what it looks like in the memory?nil 在一个可选类型中,它背后到底是什么?它在记忆中是什么样子的?
【发布时间】:2016-11-16 07:27:32
【问题描述】:
class Person{
    let name: String
    init(name: String) {
        self.name = name
    }
}

var john: Person?

上面的代码 sn-p 定义了一个名为 john 的可选类型变量。此时,变量的初始值为nil

类实例将其值保存在堆空间中,并将引用存储在堆栈中。 (如果我错了,请纠正我)john 在这种情况下是一个未分配的可选变量,它还没有引用任何实例。

问题:PC 在哪里存储名称字符串“john”?它是否已经被创建并存储在 stack 中并等待引用 heap 中的某个实例?值“nil”存储在哪里?

非常感谢

【问题讨论】:

    标签: swift class pass-by-reference optional


    【解决方案1】:

    有了这个

    var john: Person?
    

    Stack之上添加了一个内存槽。

    这个槽的类型是Optional类型的值Person

    Optional<Person>
    

    在这个内存位置中,我们找到了Optional.none 值。

    之后

    john = Person(name: "Mr Robot")
    

    一些内存被分配到Heap

    然后按照Person initializer的逻辑写入此内存。

    然后让我们回到堆栈。 这里Optional.none 被替换为值Optional.some 并且Person 对象的地址内存被写入枚举值的特殊a 字段中。

    【讨论】:

    • 感谢您的帮助和解释")
    【解决方案2】:

    在幕后,可选项实际上只是带有关联值的通用 enums:

    enum Optional<T> {
        case some(T)
        case none
    }
    

    nil 只是Optional.none 的简写。因此,在您的示例中,john 已经拥有它需要的所有存储空间;它被设置为一个值,该值恰好表示虚无。现在,由于Person 是一个类,它是一个引用类型,“它需要的所有存储空间”实际上只是一个指针的空间。与所有类实例一样,实例属性的存储将在初始化时创建。

    结论:首先有一个enum 的内存和一个指向Person 的关联指针。然后,在初始化变量之后,当然还有一个Person 实例。

    【讨论】:

    • 因此,到目前为止,john 是一个enum,但enum 是按值类型并按引用类型对其进行分类。我能说john被初始化之后,就变成了类实例。
    • 实际上,john 仍然是一个enum,一旦你初始化它,它就会获得一个指向你的类实例的指针。编译器将所有这些隐藏在 !? 运算符后面,它们从 enum 内部解开关联值并让您正常使用它。
    • 非常感谢您的帮助和解释。 ")
    猜你喜欢
    • 2019-07-05
    • 1970-01-01
    • 2011-09-08
    • 2010-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-06
    • 2010-10-26
    相关资源
    最近更新 更多