简体   繁体   English

Deinit 未调用 - 无法找到保留某些内容的原因(提供的代码)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM