iOS:如何检查UIViewControllers是否正在卸载? (迅速)

时间:2014-11-16 14:44:03

标签: ios swift uisplitviewcontroller

每次点击Master VC中的一行时,我都使用UISplitViewController我可以看到viewDidLoad()在详细VC中运行。

这是否意味着我每次点击都会创建一个新的Detail VC实例?

如果是这样,我如何检查Detail VC是否正确卸载并且我不只是创建越来越多的新Detail VC?

我在斯威夫特有点失落。以前我可以在dealloc()中使用NSLog并看到UIViewController正确卸载。

我在这里Swift有一个deinit函数,但从未调用过:

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

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

2)当我在Xcode中查看Debug Navigator时,内存使用率一直在上升而且从不下降。

更新:详细VC调用如下:

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
    }
}

我没有做过与我见过的很多例子不同的事情,但我担心deinit没有被召唤

更新:现在正在工作 - 问题是委托停止调用deinit(见下面的答案)

我原来的非工作代码是:

protocol ManageViewDelegate {
    func pressedButton(sender: AnyObject)
}

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

新工作代码:

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

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

2 个答案:

答案 0 :(得分:24)

您有一个delegate属性的视图,该属性引用回视图控制器。这将导致强大的参考周期(以前称为保留周期),因为视图控制器维持对其顶级视图的强引用,这反过来又维持了对视图控制器的强引用。

The Swift Programming Language: Automatic Reference Counting解析类实例之间的强引用周期部分中,Apple描述了如何解决这个问题:

  

当您使用类类型的属性时,Swift提供了两种解决强引用循环的方法:弱引用和无主引用。

     

弱引用和无主引用使引用周期中的一个实例能够引用另一个实例而不保持强大的保持。然后,实例可以相互引用而不会创建强大的参考周期。

     

使用weak引用,只要该引用在其生命周期的某个时刻变为nil。相反,如果您知道在初始化期间设置引用后永远不会是unowned,请使用nil引用。

因此,您可以通过将delegate定义为weak来解决强大的参考周期:

weak var delegate: ManageViewDelegate? 

要使其正常工作,您必须将协议指定为类协议:

protocol ManageViewDelegate: class {
    // your protocol here
}

这将解决强大的参考周期,无需手动nil delegate来解决强参考周期。

答案 1 :(得分:0)

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

functPtr = func;

deinit功能应该可以解决