如何检查uiviewcontroller正在卸载?(迅速)

时间:2022-10-25 15:03:05

I'm using a UISplitViewController every time I click on a row in the Master VC I can see that viewDidLoad() is run in the Detail VC.

我在使用UISplitViewController每次我点击主VC中的一行时我都能看到viewDidLoad()在Detail VC中运行。

Does this mean i'm creating a new instance of Detail VC each row click?

这是否意味着我要创建一个新的细节VC实例,每一行点击一次?

If so, how can I check that the Detail VC are unloading correctly and that i'm not just creating more and more new Detail VCs?

如果是,我如何检查细节VC是否正确卸载,以及我是否只是创建越来越多的细节VC ?

I'm a bit lost here in Swift. Previously I could NSLog in dealloc() and see the UIViewController correctly unloading.

我在斯威夫特这儿有点迷路了。以前,我可以在dealloc()中使用NSLog,并正确地看到UIViewController的卸载。

I here Swift has a deinit function but this is never called:

我这里Swift有一个deinit函数,但这从来没有被调用:

deinit {
    println("\(__FILE__.lastPathComponent)) : \(__FUNCTION__)")
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

1) Where should I be removing my observers?

1)我应该把我的观察员移到哪里?

2) When I look in the Debug Navigator in Xcode the Memory usage just keeps going up and never down.

2)当我在Xcode中查看调试导航器时,内存使用一直在增加,从来没有减少。

Updated: Detail VC is being called as follows:

if segue.identifier == "addEvent" {
    if let controller = (segue.destinationViewController as UINavigationController).topViewController as? ManageViewController {
        controller.manageEvent = nil
        controller.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem()
        controller.navigationItem.leftItemsSupplementBackButton = true
    }
}

I'm not doing anything different than lots of examples i've seen, but I am worried about deinit not being called

我没有做任何与我看到的例子不同的事情,但是我担心deinit没有被调用。

Updated: Working now - Problem was with delegate stopping deinit being called (see below answer)

My original Non-Working code was:

我最初的非工作代码是:

protocol ManageViewDelegate {
    func pressedButton(sender: AnyObject)
}

class ManageView: UIView {
    var delegate: ManageViewDelegate? = nil
    ...
}

New Working code:

新工作代码:

protocol ManageViewDelegate: class {
    func pressedButton(sender: AnyObject)
}

class ManageView: UIView {
    weak var delegate: ManageViewDelegate? = nil
    ...
}

2 个解决方案

#1


24  

You have a view with a delegate property that references back to the view controller. This will result in a strong reference cycle (previously known as a retain cycle) because the view controller is maintaining a strong reference to its top level view which is, in turn, maintaining a strong reference back to the view controller.

您有一个具有委托属性的视图,该属性引用视图控制器。这将导致一个强引用周期(以前称为保留周期),因为视图控制器维护对其顶层视图的强引用,反过来,维护对视图控制器的强引用。

In the Resolving Strong Reference Cycles Between Class Instances section of The Swift Programming Language: Automatic Reference Counting, Apple describes how to address this:

在解决快速编程语言的类实例部分之间的强引用周期:自动引用计数,苹果描述了如何解决这个问题:

Swift provides two ways to resolve strong reference cycles when you work with properties of class type: weak references and unowned references.

当您使用类类型的属性时,Swift提供了两种解决强引用周期的方法:弱引用和未引用引用。

Weak and unowned references enable one instance in a reference cycle to refer to the other instance without keeping a strong hold on it. The instances can then refer to each other without creating a strong reference cycle.

弱引用和非拥有引用使引用循环中的一个实例可以引用另一个实例,而不必对它保持强引用。然后,这些实例可以相互引用,而不创建强引用循环。

Use a weak reference whenever it is valid for that reference to become nil at some point during its lifetime. Conversely, use an unowned reference when you know that the reference will never be nil once it has been set during initialization.

使用弱引用,无论何时该引用在其生命周期的某一时刻为nil时都是有效的。相反,当您知道在初始化期间设置引用将永远不会为nil时,请使用未拥有的引用。

Thus, you can resolve your strong reference cycle by defining the delegate to be weak:

因此,您可以通过定义委托为弱来解决强引用循环:

weak var delegate: ManageViewDelegate? 

For that to work, you have to specify your protocol to be a class protocol:

为此,您必须指定您的协议为一个类协议:

protocol ManageViewDelegate: class {
    // your protocol here
}

That will resolve the strong reference cycle and eliminates the need to manually nil the delegate in order to resolve the strong reference cycle.

这将解决强引用循环,并消除手动nil委托以解决强引用循环的需要。

#2


0  

Also if you use blocks you need to add [weak self], otherwise,the view wouldn't be destroyed

另外,如果您使用块,您需要添加[弱自我],否则视图不会被破坏

 setupObserve(postID) {
        [weak self] chatRequest in
    self?.update()
 }

The deinit function should work out

deinit函数应该可以工作

#1


24  

You have a view with a delegate property that references back to the view controller. This will result in a strong reference cycle (previously known as a retain cycle) because the view controller is maintaining a strong reference to its top level view which is, in turn, maintaining a strong reference back to the view controller.

您有一个具有委托属性的视图,该属性引用视图控制器。这将导致一个强引用周期(以前称为保留周期),因为视图控制器维护对其顶层视图的强引用,反过来,维护对视图控制器的强引用。

In the Resolving Strong Reference Cycles Between Class Instances section of The Swift Programming Language: Automatic Reference Counting, Apple describes how to address this:

在解决快速编程语言的类实例部分之间的强引用周期:自动引用计数,苹果描述了如何解决这个问题:

Swift provides two ways to resolve strong reference cycles when you work with properties of class type: weak references and unowned references.

当您使用类类型的属性时,Swift提供了两种解决强引用周期的方法:弱引用和未引用引用。

Weak and unowned references enable one instance in a reference cycle to refer to the other instance without keeping a strong hold on it. The instances can then refer to each other without creating a strong reference cycle.

弱引用和非拥有引用使引用循环中的一个实例可以引用另一个实例,而不必对它保持强引用。然后,这些实例可以相互引用,而不创建强引用循环。

Use a weak reference whenever it is valid for that reference to become nil at some point during its lifetime. Conversely, use an unowned reference when you know that the reference will never be nil once it has been set during initialization.

使用弱引用,无论何时该引用在其生命周期的某一时刻为nil时都是有效的。相反,当您知道在初始化期间设置引用将永远不会为nil时,请使用未拥有的引用。

Thus, you can resolve your strong reference cycle by defining the delegate to be weak:

因此,您可以通过定义委托为弱来解决强引用循环:

weak var delegate: ManageViewDelegate? 

For that to work, you have to specify your protocol to be a class protocol:

为此,您必须指定您的协议为一个类协议:

protocol ManageViewDelegate: class {
    // your protocol here
}

That will resolve the strong reference cycle and eliminates the need to manually nil the delegate in order to resolve the strong reference cycle.

这将解决强引用循环,并消除手动nil委托以解决强引用循环的需要。

#2


0  

Also if you use blocks you need to add [weak self], otherwise,the view wouldn't be destroyed

另外,如果您使用块,您需要添加[弱自我],否则视图不会被破坏

 setupObserve(postID) {
        [weak self] chatRequest in
    self?.update()
 }

The deinit function should work out

deinit函数应该可以工作