[英]Deinit not calling - Cannot find why something is retaining (code provided)
I have discovered that my UIViewcontroller is not calling deinit()
under the following scenario.我发现我的 UIViewcontroller 在以下情况下没有调用
deinit()
。 I am using this code extension to make my life easier by adding tap gesture recognizers.我正在使用这个代码扩展,通过添加点击手势识别器让我的生活更轻松。
https://gist.github.com/saoudrizwan/548aa90be174320fbaa6b3e71f01f6ae https://gist.github.com/saoudrizwan/548aa90be174320fbaa6b3e71f01f6ae
I've used this code in one of my VCs, which I've stripped down to the barest minimum amount of code:我在我的一个 VC 中使用了这段代码,我已经将其精简到最少的代码量:
and in viewDidLoad()
I did this:在
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()
}
It appears that the line:看来该行:
self.txtSubject.becomeFirstResponder()
Is the problem - when I leave this line above in that closure, deinit()
does not call in my VC.是问题所在 - 当我在该闭包中离开上面的这一行时,
deinit()
不会在我的 VC 中调用。 When I take the above line out or replace it with something like print("hello world")
deinit()
properly calls.当我取出上面的行或将其替换为
print("hello world")
deinit()
正确调用时。 txtSubject is @IBOutlet weak var txtSubject: UITextField!
txtSubject 是
@IBOutlet weak var txtSubject: UITextField!
I am not entirely sure what to do here.我不完全确定在这里做什么。 I read that when you trigger
becomeFirstResponder()
it's important you call resignFirstResponder()
, but even if I don't tap the label (so as to not give becomeFirstResponder()
a chance to even call) I still cannot hit deinit()
我读到,当您触发
becomeFirstResponder()
时,调用resignFirstResponder()
很重要,但即使我不点击 label (以免给becomeFirstResponder()
打电话的机会)我仍然无法点击deinit()
Any ideas where I can look further?有什么想法可以让我进一步了解吗?
Thanks so much.非常感谢。
Change改变
self.txtSubject.becomeFirstResponder()
To至
[unowned self] in self.txtSubject.becomeFirstResponder()
unowned
is often feared as dangerous, but there is no danger here. unowned
通常被认为是危险的,但这里没有危险。 If self
ceases to exist, there will be nothing to tap and the code will never run.如果
self
不复存在,将没有任何东西可以点击,代码将永远不会运行。
This is a classic retain loop.这是一个经典的保留循环。 The
self.
self.
inside of the closure is there to remind you to think about this.里面的封包提醒你思考这个问题。 I assume that
self
is retaining lblSubject
, and (via a OBJC_ASSOCIATION_RETAIN
associated key), lblSubject
is retaining self
because it's captured by this closure.我假设
self
保留lblSubject
,并且(通过OBJC_ASSOCIATION_RETAIN
关联键), lblSubject
保留self
因为它被此闭包捕获。
You don't really need self
here, however.但是,您在这里并不需要
self
。 You just need txtSubject
.你只需要
txtSubject
。 So you can just capture that:所以你可以捕捉到:
lblSubject.addTapGestureRecognizer { [txtSubject] in
txtSubject.becomeFirstResponder()
}
Alternately, you can fall back to the giant weak self
hammer (though this tends to be greatly over-used):或者,您可以退回到巨大的
weak self
锤(尽管这往往被过度使用):
lblSubject.addTapGestureRecognizer { [weak self] in
self?.txtSubject.becomeFirstResponder()
}
The best way to explore this kind of bug is with Xcode's Memory Graph .探索这种错误的最佳方法是使用 Xcode 的Memory Graph 。
It is also a good idea to review the Swift docs on Automatic Reference Counting .查看有关Automatic Reference Counting的 Swift 文档也是一个好主意。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.