我有一个名为PERSON的类来测试内存泄漏。以下是课程内容:
let name: String
private var actionClosure: (() -> ())!
init (name: String) {
self.name = name
self.actionClosure = {
println("I am \(self.name)")
}
}
func performAction () {
actionClosure()
}
deinit {
println("\(name) is being deinitialized")
}
无论如何,我正在关注的书在ViewController.swift中写了一个代码。在viewDidLoad()方法下面。这是内容:
let person = Person(name: "randomName"); person.performAction();
我不理解的部分是:我们用String初始化一些东西。我明白了,但是这个班怎么能直接使用呢?就像它知道采用那个init一样?我真的不明白那里发生了什么。如果有人可以解释课程及其中发生的事情,那将是非常棒的。
答案 0 :(得分:1)
在Person
类中,您已定义了一个接受String
作为参数的初始化程序。
init (name: String)
尝试添加其他类似的初始化工具
init (name: String) {
self.name = name
self.actionClosure = {
println("I am \(self.name)")
}
}
init(someOtherName: String) {
self.name = someOtherName
self.actionClosure = {
println("I am \(self.name)")
}
}
有了这个,你已经定义了两个初始化者,你可以调用原来的
let person = Person(name: "randomName")
或者你可以致电
let person = Person(someOtherName: "randomName")
他们将执行相同的初始化。我希望这能回答你的问题
答案 1 :(得分:1)
您的Person
对象会泄漏,因为您有“强参考周期”。该类拥有actionClosure
(即强烈引用它),但actionClosure
有强烈的引用回self
。
您的关闭应该使用weak
或unowned
引用self
来打破这个强大的参考周期:
self.actionClosure = { [unowned self] in
println("I am \(self.name)")
}
这将解决强大的参考周期。
你问“怎么知道接受init
?”它根据您提供的参数的名称和类型知道要调用哪个init
。
考虑您的init
实施如下:
init (name: String) { ... }
这需要name
类型为String
的参数。因此,要以使用init
方法的方式实例化对象,您可以使用类名,例如: Person
,其参数名为name
,类型为String
,例如:
let person = Person(name: "Rob")
请参阅 Swift编程语言指南的Initialization章节。