class Increment {
   var number = 0
 
   init(){
       print(#function)
    }
   deinit {
       print(#function)
   }
   //    let incrementNumber would give an error — 1
   lazy var incrementNumber: (Int) -> () = { [weak self] value in
       self?.number += value
       print(self?.number)
   }
}
 
do {
   let increment = Increment().incrementNumber(3)
}
// output
init()
deinit
nil

如果我分隔这行,那么当执行闭包时,self仍然是活动的.

let increment = Increment()
increment.incrementNumber(3)
// output
init()
Optional(3)
deinit

有没有人能解释一下,为什么在incrementNumber()呼叫之前,Increment人得到了提示?

推荐答案

首先,您需要知道惰性变量的定义.

根据apple docs的说法,惰性存储属性是指直到第一次使用时才计算其初始值的属性.您可以通过在声明之前编写lazy修饰符来指示惰性存储属性.

这意味着当类是初始类时,他们不知道里面有变量lazy,它是incrementNumber.

你打电话给我的原因是

do {
   let increment = Increment().incrementNumber(3)
}

当您直接访问时,Increment不识别类中的incrementNumber.因此,SWIFT只看到您对其余代码中的Increment类不做任何操作,然后它会自动将未使用的类deinit.

Update:正如DuncanC先生所提到的,由于deinit类是第一类,所以编译器创建Increment的实例作为AutoRelease,并将其保存在内存中,以便计算表达式的第二部分

在第二个阶段,您可以调用

let increment = Increment()
increment.incrementNumber(3)

意味着您首先创建一个类,然后创建LAZY变量(Swift发现您在第二行对该类做了一些操作,所以它会一直等到类中的所有内容都被调用).然后,在代码的其余部分中,类Increment未使用,然后它自动deinit.这就是你看到懒惰先于deinit的原因.

对于更深入的知识,你可以做一些事情,比如打not lazy function分来看看不同之处.

class Increment {
   var number = 0

   init(){
       print(#function)
    }

   deinit {
       print(#function)
   }

    public func increaseNumber(_ value: Int) {
        self.number += value
        print(#function)
    }
}

do {
    let increment = Increment().increaseNumber(3)
}

//init()
//increaseNumber(_:)
//deinit

正如您所看到的,increaseNumberdeinit之前被调用,因为类知道它拥有Func increaseNumber,所以它被调用.则在代码的其余部分中,类Increment未被使用,则它自动deinit.

Swift相关问答推荐

如何更新Square Order?

@ MainActor + Combine不一致的编译器错误

更改正在进行的异步任务的完成(SWIFT并发)(&q;)?

如何为任务扩展的泛型静态函数获得自动类型推理

在SWIFT中使用Objective-C struct 时出错(在作用域中找不到类型)

仅当单击UIButton时才调用计时器函数

SwiftData/PersistentModel.swft:540:致命错误:不支持的关系密钥路径ReferenceWritableKeyPath

如何将函数参数(字符串文字)标记为可本地化?

在Swift中,将秒设置为0也等于将1添加到分钟

如何观察UIViewRepresentable中的多个变化?

SwiftUI 组合问题:通过 AppEventsManager 在 ViewModel 之间共享数据

无论玩家移动到视图内的哪个位置,如何使用 SpriteKit 让敌人向玩家emits 子弹?

如何使用Swift宏和@Observable和@Environment?

带有可选字符串作为键路径的 SwiftUI iOS16 表

如何让 UIKit 挤压你的视图,使其适合屏幕

阻止其他类型的键盘

如何从 Button 获取标签名称?

在 Swiftui 中是否有一种简单的方法可以通过捏合来放大图像?

UIButton 标题左对齐问题 (iOS/Swift)

如何在 SwiftUI 中的一个视图上显示两个alert ?