Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift中Lazy-var和var-as-a-closure的区别_Swift_Lazy Initialization - Fatal编程技术网

Swift中Lazy-var和var-as-a-closure的区别

Swift中Lazy-var和var-as-a-closure的区别,swift,lazy-initialization,Swift,Lazy Initialization,我创建了一些示例项目来测试各种类型的变量实现,以测试哪些变量只执行一次,哪些变量每次调用都执行 class Something:NSObject { var clock:Int = 0 override var description: String { let desc = super.description clock += 1 return "\(desc) Clock: \(clock)" } } stat

我创建了一些示例项目来测试各种类型的变量实现,以测试哪些变量只执行一次,哪些变量每次调用都执行

class Something:NSObject
{
    var clock:Int = 0
    override var description: String
    {
        let desc = super.description
        clock += 1
        return "\(desc) Clock: \(clock)"
    }
}

static var staticVar:Something
{
    print("static Var")
    return Something()
}
static var staticVar2:Something = {
    print("static Var II")
    return Something()
}()

lazy var lazyVar:Something = {
    print("lazy Var")
    return Something()
}()

var simpleVar:Something {
    print("simple Var")
    return Something()
}

var simpleVar2:Something = {
    print("simple Var II")
    return Something()
}()
然后在
viewDidLoad()
(确保变量已经初始化)中,调用所有变量几次并保存在数组中以保持引用的强度

var strongArr = [Something]()

print("== STATIC VAR")
strongArr.append(ViewController.staticVar)
print(strongArr.last!.description)
strongArr.append(ViewController.staticVar)
print(strongArr.last!.description)
strongArr.append(ViewController.staticVar)
print(strongArr.last!.description)

print("\n== STATIC VAR {}()")
strongArr.append(ViewController.staticVar2)
print(strongArr.last!.description)
strongArr.append(ViewController.staticVar2)
print(strongArr.last!.description)
strongArr.append(ViewController.staticVar2)
print(strongArr.last!.description)

print("\n== SIMPLE VAR")
strongArr.append(self.simpleVar)
print(strongArr.last!.description)
strongArr.append(self.simpleVar)
print(strongArr.last!.description)
strongArr.append(self.simpleVar)
print(strongArr.last!.description)

print("\n== SIMPLE VAR {}()")
strongArr.append(self.simpleVar2)
print(strongArr.last!.description)
strongArr.append(self.simpleVar2)
print(strongArr.last!.description)
strongArr.append(self.simpleVar2)
print(strongArr.last!.description)

print("\n== LAZY VAR {}()")
strongArr.append(self.lazyVar)
print(strongArr.last!.description)
strongArr.append(self.lazyVar)
print(strongArr.last!.description)
strongArr.append(self.lazyVar)
print(strongArr.last!.description)
这是在控制台中注销的结果

== STATIC VAR
static Var
<_TtCC8DemoDemo14ViewController9Something: 0x600003725100> Clock: 1
static Var
<_TtCC8DemoDemo14ViewController9Something: 0x600003725160> Clock: 1
static Var
<_TtCC8DemoDemo14ViewController9Something: 0x600003725270> Clock: 1

== STATIC VAR {}()
static Var II
<_TtCC8DemoDemo14ViewController9Something: 0x6000037251b0> Clock: 1
<_TtCC8DemoDemo14ViewController9Something: 0x6000037251b0> Clock: 2
<_TtCC8DemoDemo14ViewController9Something: 0x6000037251b0> Clock: 3

== SIMPLE VAR
simple Var
<_TtCC8DemoDemo14ViewController9Something: 0x600003725240> Clock: 1
simple Var
<_TtCC8DemoDemo14ViewController9Something: 0x6000037252a0> Clock: 1
simple Var
<_TtCC8DemoDemo14ViewController9Something: 0x6000037252b0> Clock: 1

== SIMPLE VAR {}()
<_TtCC8DemoDemo14ViewController9Something: 0x600003738100> Clock: 1
<_TtCC8DemoDemo14ViewController9Something: 0x600003738100> Clock: 2
<_TtCC8DemoDemo14ViewController9Something: 0x600003738100> Clock: 3

== LAZY VAR {}()
lazy Var
<_TtCC8DemoDemo14ViewController9Something: 0x60000372ea70> Clock: 1
<_TtCC8DemoDemo14ViewController9Something: 0x60000372ea70> Clock: 2
<_TtCC8DemoDemo14ViewController9Something: 0x60000372ea70> Clock: 3
==静态变量
静态变量
时钟:1
静态变量
时钟:1
静态变量
时钟:1
==静态变量{}()
静态变量II
时钟:1
时钟:2
时钟:3点
==简单变量
简单变量
时钟:1
简单变量
时钟:1
简单变量
时钟:1
==简单变量{}()
时钟:1
时钟:2
时钟:3点
==惰性变量{}()
惰性变量
时钟:1
时钟:2
时钟:3点
基于这些测试,如果lazy-var和simple-var都被定义为闭包(
()
),那么它们之间似乎没有区别


作为闭包的变量实现会自动使变量变懒吗?还是我遗漏了什么?

区别在于变量的初始化代码何时运行。对于
lazy
vars,init代码在第一次访问该变量时运行。对于
non-lazy
vars,它在初始化结构/类时运行

struct N {
    lazy var a: Int = { print("Setting A"); return 5}();
    var b: Int = { print("Setting B"); return 5 }()
}

var n = N()
print(n.a)
print(n.b)
输出:

Setting B
Setting A
5
5

注意非惰性
b
是如何首先初始化的<代码>仅在访问时才对其进行初始化。在这两种情况下,每个属性的初始值设定项只运行一次。

当您将它们与结构/类的其他属性混合时,它们会得到更多的相互测试。我可以想到以下几点:

作为闭包的var不能引用其他实例变量 原因是var as闭包是在初始化期间计算的,Swift不保证首先初始化哪个属性<当初始化
fullName2
时,code>firstName和
lastName
可能尚未初始化

不能定义包含惰性变量的结构的常量实例 一个
lazy var
是在您第一次读取它时计算出来的,因此根据定义,它会改变结构。因此,
让p=Person(…)
无效。您必须使用
var p=Person(…)


但是,如果
Person
是一个类,您可以使用
让p=Person(…)
,因为这里的“常量”表示
p
指向一个固定的内存地址,但是该地址的对象可以随时更改。

时钟变量应该表示什么?调用描述方法的次数?@brett,它是为了确保在时钟增加时调用相同的对象。在引入数组的强引用之前,我在测试中遇到了一些问题-相同的地址显示相同的时钟数,这意味着不同的对象被分配到相同的地址点(一旦对象被释放,另一个对象甚至在相同的线程上运行,正如您在上面的示例项目中看到的那样)。谢谢!不知怎的,我错过了日志的第一行,它显示了和你们在这里所说的完全相同的东西——var-as-a-closure是和父类一起启动的,而lazy是为了节省内存,以确保只在需要时分配它
struct Person {
    var firstName: String
    var lastName: String

    lazy var fullName1 = "\(firstName) \(lastName)"             // OK
    var fullName2: String = { "\(firstName) \(lastName)" }()    // invalid

    init(firstName: String, lastName: String) {
        self.firstName = firstName
        self.lastName = lastName
    }
}
let p = Person(firstName: "John", lastName: "Smith")
print(p.fullName1)                                      // runtime error