我希望释放我的ViewController在解除它后使用的内存。我使用以下代码来呈现新的ViewController并解除旧的ViewController:
let sB: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newVC: UIViewController = sB.instantiateViewController(withIdentifier: "MyVC")
self.present(newVC, animated: true, completion: { x in
oldVC.dismiss(animated: false, completion: { _ in //oldVC: variable keeping track of currently visible view controller
print("done")
})
})
此代码成功显示newVC
并在解除done
后打印oldVC
。但是,我的记忆仍然保持在屏幕上oldVC
时的记忆力
我做错了什么?
presentingViewController
和presentedViewController
均为nil
答案 0 :(得分:4)
检查以下问题:
<强>解决方案:强>
UINavigationController
并使用setViewControllers
来管理ViewControllers的转换。oldVC
如果你真的不明白。你可以搜索:
答案 1 :(得分:3)
您的oldVC
将不会被取消分配,因为您的newVC
(以及任何UIViewController
)默认保留对其presentingViewController
的强引用 - 显示它的控制器。如果不是这种情况,您将永远无法在不打扰视图层次结构的情况下安全地关闭newVC
。
就您的具体问题而言,为了解除分配您的旧视图控制器,我建议先解除oldVC
,然后在堆栈前面的另一个ViewController中显示您的newVC
(可以是UIApplication shared().keyWindow?.rootViewController
)
答案 2 :(得分:3)
我对UINavigationController
的推/弹有同样的问题。 @spassas对于强引用是正确的,这是您newVC
未被释放的原因。您应该仔细查看newVC
。
在我的情况下(用Objective-C编写),有另一个视图控制器被引用作为推送视图控制器的私有属性(你的newVC
):
EventActionSheetViewController* actionSheet;
actionSheet
对推送的视图控制器(newVC
)有强烈的引用作为其委托:
@property (nonatomic) id<EventActionSheetDelegate> delegate;
我一直在检查我的应用程序的内存,发现推送的视图控制器在被导航控制器弹出后没有被释放。几个小时后,我将强引用改为弱,并且结果很明显:
@property (nonatomic, weak) id<EventActionSheetDelegate> delegate;
问题是我推送的视图控制器及其EvenetActionSheetViewController
对彼此有很强的引用,并且不知何故没有让对方解除分配。
我建议您检查newVC
是否有类似的强引用循环,并尽可能将它们更改为弱。在Swift中使用weak let
或weak var
代替let/var
。希望这可以帮助您找到错误。
答案 3 :(得分:1)
尝试使用以下代码替换您的代码:
let appDel = UIApplication.shared.delegate as! AppDelegate
let sB: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newVC = sB.instantiateViewController(withIdentifier: "MyVC")
appDel.window?.rootViewController = newVC
appDel.window?.makeKeyAndVisible()
希望这有效!
编辑: 您还可以通过将以下代码添加到所有视图控制器来检查旧的View Controller是否已被取消初始化:
deinit {
debugPrint("Name_Of_View_Controller deinitialized...")
}
编辑2:
如果要保留视图控制器中的演示流程,并且只想关闭最后一个视图控制器,即
在过渡期间:masterVC - &gt; oldVC - &gt; NEWVC
从oldVC过渡到newVC后,你想返回masterVC,释放oldVC的内存。 您可以将masterVC引用传递给oldVC并实现您想要的内容:
if(masterVC != nil) {
oldVC.dismiss(animated: false, completion: {
let sB: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newVC = sB.instantiateViewController(withIdentifier: "vc2")
self.masterVC!.present(newVC, animated: false, completion: {
print("done")
})
})
}
这适用于你陈述的情况。