Deinit从未打电话过

Yog*_*ton 48 uinavigationcontroller swift deinit

我正在创建一个ViewController对象,将其推送到导航控制器.当从堆栈弹出对象时 - 它没有被释放而Deinit没有被调用.可能是什么原因?

这是推送的代码:

self.navigationController?.pushViewController(CustomViewController(), animated: true)
Run Code Online (Sandbox Code Playgroud)

这是弹出的代码:

 self.navigationController?.popViewControllerAnimated(true)
Run Code Online (Sandbox Code Playgroud)

Vla*_*pko 64

我有类似的问题.我deinit在我的类中添加了空方法并添加了断点:

deinit {

}
Run Code Online (Sandbox Code Playgroud)

结果它从未被调用过.
只要我向主体添加一些代码,它就会按预期开始工作:

deinit {
    print("deinit called")
}
Run Code Online (Sandbox Code Playgroud)

所以请确保您的deinit方法不为空.
PS.我使用的是Swift 2,Xcode 7.1

  • 我和你有完全相同的问题.我发现这是因为[断点只能在`deinit`中工作,如果前面有可执行的代码行.](http://stackoverflow.com/a/33788952/35690) (3认同)
  • @Duan这是编译器优化的一部分,其中在最终二进制文件中跳过了没有实现的空方法。 (3认同)
  • 为了避免这个问题而不编写 `deinit` 方法,您可以在 `ClassName.deinit` 上创建一个符号断点。这里有一个很好的解释如何做到这一点:https://www.bignerdranch.com/blog/xcode-breakpoint-wizardry/ (2认同)

cle*_*ght 49

您的任何类或它们包含的属性是否会引用您弹出的视图控制器?

如果您的UIViewController已经创建了一个对象的实例,而该对象又对该视图控制器进行了"强烈"引用(例如,未明确声明为'weak'或'unowned'的引用),并且您的视图控制器保持强引用该对象也将被解除分配.这称为强引用循环,在此处记录(对于严肃的Swift开发人员必读):

Swift编程语言(Swift 3.0.1):自动引用计数

关闭是一个更加阴险的案例,您可能会遇到麻烦.

您可以尝试作为实验的一件事是推动控制器并在您在viewDidLoad或初始化中执行任何操作之前弹出它,并查看是否正在调用deinit方法.如果是,那么你应该能够逐步发现你正在做的事情,这会导致你所看到的症状.

另一件可能阻碍诊断的事情(正如其他答案所指出的那样),我学到了很难的方法,如果deinit方法不包含可执行语句,则调试器断点不会被用于deinit(),因为操作系统或编译器如果它是空的,那么优化deinit调用,所以如果你想验证deinit()被调用,至少要在那里放一个print语句.

  • 谢谢,非常有帮助! (2认同)

MB_*_*per 16

我在给定页面上使用本教程Custom TabBar和自定义seque.内存问题是由于子视图具有父视图控制器的强引用.

class WBMNewsFeedV: UIView
{
   var parentVC:WBMHomeTabVC!
}
Run Code Online (Sandbox Code Playgroud)

WBMNewsFeedV - 子类

parentVC:WBMHomeTabVC - 父类ViewController

我改成了:

class WBMNewsFeedV: UIView
{
    weak var parentVC:WBMHomeTabVC!
}
Run Code Online (Sandbox Code Playgroud)

因此,强引用嵌套在子视图中,并且最初不可见.希望这有助于任何人.改变后,deinit总是被调用

WBMHomeTabVC

  • 有同样的问题.为了找到我在我的``ViewController`中搜索`self`的引用,找到我传给它的所有地方作为参考存储在委托变量中.显然三个中的一个没有被设定为"弱" (4认同)

Dav*_*dez 11

当NotificationCenter对所呈现的视图进行强有力的引用时,我遇到了同样的问题,因此它永远不会被释放.所以我不得不像这样添加[弱自我]到块:

(在viewDidLoad中)

NotificationCenter.default.addObserver(forName: .showFoo, object: nil, 
  queue: OperationQueue.main) { [weak self] (notification) in
    if let foo = notification.userInfo?["foo"] as? Foo {
            self?.afooButton!.setImage(UIImage(named: "foo"), for: .normal)
    }
}
Run Code Online (Sandbox Code Playgroud)


Dev*_*esh 8

添加一些deinit的行代码.如果你把断点放在Empty deinit,编译器不会阻止你把它放在:

deinit {
print("any thing")
}
Run Code Online (Sandbox Code Playgroud)

它会工作;)


CMa*_*ash 7

我的视图控制器中有一个计时器,每分钟运行一次以更新标签.我用deinit调用来使计时器无效,我很确定这是我在Objective-C(在dealloc中)所做的一切,并且它有效.但是在Swift中似乎有点不同,所以我将时间创建/失效代码移动到viewWillAppear/viewWillDisappear(这真的更有意义),现在一切似乎都很好!


nwa*_*les 6

我刚遇到类似的问题.我的问题似乎是由对一个控件的强引用引起的,该控件的委托赋值没有被指定为带有类类型协议的"弱".

  • 优胜者!有一个`@objc协议'并忘了标记是弱的.感谢您的提醒. (3认同)

mru*_*nki 5

我遇到了同样的问题,我发现我没有为其他班级代表提供弱引用

protocol SomeClassDelegate : AnyObject {
    func someClassDelegateMethod(<param>)
}

class SomeClass: NSObject {

    // Make delegate weak reference 
    weak var delegate:InfractionDataManagerDelegate? = nil
    < some code >
}
Run Code Online (Sandbox Code Playgroud)

现在deinit正在我的实现类上被调用。