Deinit 不调用 - 找不到保留某些内容的原因(提供的代码)
Deinit not calling - Cannot find why something is retaining (code provided)
我发现在以下情况下我的 UIViewcontroller 没有调用 deinit()
。
我正在使用此代码扩展通过添加点击手势识别器让我的生活更轻松。
https://gist.github.com/saoudrizwan/548aa90be174320fbaa6b3e71f01f6ae
我已经在我的 VC 之一中使用了这段代码,我已经将其精简到最少的代码量:
在 viewDidLoad()
中我这样做了:
// When the user taps on a label, have its related textbox automatically get the caret so they can type
// Add tapping so when you tap on a label it makes the corresponding textbox first responder
lblSubject.addTapGestureRecognizer {
self.txtSubject.becomeFirstResponder()
}
似乎是行:
self.txtSubject.becomeFirstResponder()
是问题所在 - 当我在那个闭包中留下上面这一行时,deinit()
没有调用我的 VC。
当我删除上面的行或将其替换为 print("hello world")
之类的内容时
deinit()
正确调用。 txtSubject 是 @IBOutlet weak var txtSubject: UITextField!
我不太确定在这里做什么。我读到当你触发 becomeFirstResponder()
时调用 resignFirstResponder()
很重要,但即使我不点击标签(以免给 becomeFirstResponder()
一个调用的机会)我仍然打不中 deinit()
有什么我可以进一步研究的想法吗?
非常感谢。
这是一个经典的保留循环。闭包内部的 self.
是为了提醒您考虑这一点。我假设 self
保留了 lblSubject
,并且(通过 OBJC_ASSOCIATION_RETAIN
关联的键),lblSubject
保留了 self
因为它被这个闭包捕获了。
不过,您实际上并不需要 self
。你只需要txtSubject
。所以你可以捕捉到:
lblSubject.addTapGestureRecognizer { [txtSubject] in
txtSubject.becomeFirstResponder()
}
或者,您可以退回到巨型 weak self
锤子(尽管这往往被过度使用):
lblSubject.addTapGestureRecognizer { [weak self] in
self?.txtSubject.becomeFirstResponder()
}
探索此类错误的最佳方法是使用 Xcode 的 Memory Graph。
查看 Automatic Reference Counting 上的 Swift 文档也是一个好主意。
改变
self.txtSubject.becomeFirstResponder()
到
[unowned self] in self.txtSubject.becomeFirstResponder()
unowned
通常被认为是危险的,但这里没有危险。如果 self
不复存在,将没有任何东西可以挖掘,代码将永远不会 运行.
我发现在以下情况下我的 UIViewcontroller 没有调用 deinit()
。
我正在使用此代码扩展通过添加点击手势识别器让我的生活更轻松。
https://gist.github.com/saoudrizwan/548aa90be174320fbaa6b3e71f01f6ae
我已经在我的 VC 之一中使用了这段代码,我已经将其精简到最少的代码量:
在 viewDidLoad()
中我这样做了:
// When the user taps on a label, have its related textbox automatically get the caret so they can type
// Add tapping so when you tap on a label it makes the corresponding textbox first responder
lblSubject.addTapGestureRecognizer {
self.txtSubject.becomeFirstResponder()
}
似乎是行:
self.txtSubject.becomeFirstResponder()
是问题所在 - 当我在那个闭包中留下上面这一行时,deinit()
没有调用我的 VC。
当我删除上面的行或将其替换为 print("hello world")
之类的内容时
deinit()
正确调用。 txtSubject 是 @IBOutlet weak var txtSubject: UITextField!
我不太确定在这里做什么。我读到当你触发 becomeFirstResponder()
时调用 resignFirstResponder()
很重要,但即使我不点击标签(以免给 becomeFirstResponder()
一个调用的机会)我仍然打不中 deinit()
有什么我可以进一步研究的想法吗?
非常感谢。
这是一个经典的保留循环。闭包内部的 self.
是为了提醒您考虑这一点。我假设 self
保留了 lblSubject
,并且(通过 OBJC_ASSOCIATION_RETAIN
关联的键),lblSubject
保留了 self
因为它被这个闭包捕获了。
不过,您实际上并不需要 self
。你只需要txtSubject
。所以你可以捕捉到:
lblSubject.addTapGestureRecognizer { [txtSubject] in
txtSubject.becomeFirstResponder()
}
或者,您可以退回到巨型 weak self
锤子(尽管这往往被过度使用):
lblSubject.addTapGestureRecognizer { [weak self] in
self?.txtSubject.becomeFirstResponder()
}
探索此类错误的最佳方法是使用 Xcode 的 Memory Graph。
查看 Automatic Reference Counting 上的 Swift 文档也是一个好主意。
改变
self.txtSubject.becomeFirstResponder()
到
[unowned self] in self.txtSubject.becomeFirstResponder()
unowned
通常被认为是危险的,但这里没有危险。如果 self
不复存在,将没有任何东西可以挖掘,代码将永远不会 运行.