UIViewController的一个坑

起因

前段时间,我们的项目有一个需求,需要判断一个vc究竟是present出来的还是push出来的,当然实现方法多种多样。最简单的方法莫过于增加一个属性存储,需要的时候直接判断,这也是一个比较安全,比较常规的方法。当然如果用到这个方法也就没有这篇文章了。下面说下我的方法以及遇到的一个坑。

我的解决方法

最开始我的解决方法是通过UIViewController的属性

1
open var isBeingPresented: Bool { }

来判断,但是遇到了一个问题,当我在vc中刷新webview后在进行判断发现用这个属性来判断会出现错误,于是查下是否有其他的属性能满足我的需求。于是有了下面的代码

1
2
3
4
5
6
7
if presentationController != nil {
print("presentationController")
}
if navigationController?.presentationController != nil {
print("navigationController presentationController")
}

当然这是错误的用法

遇到的问题

当时上面的做法是一个错误的方法,但表面上来看不会出现什么的样问题。比较奇怪的是使用后发现引起了内存泄漏,之前的vc得不到释放。然

1
open var presentationController: UIPresentationController? { get }

只是一个get属性,用来判断理论上不会有相互持有的情况,所以理论上也不会出现得不到释放问题。出现之后觉得比较奇怪,调查下发现UIPresentationController是iOS8出现的主要用来实现自定义转场动画的。但之前的疑惑并没有得到解决,目前只能怀疑是苹果本身的一个bug。如果有人遇到同样的问题,并且了解具体的原因,还希望告知,万分感谢。

判断vc是否是presnet的一个比较合适的方法

接下来提供一个判断vc是否是present的方法,也是我现在用到的一个依据,依然是UIViewController的属性

1
2
3
4
@available(iOS 5.0, *)
open var presentedViewController: UIViewController? { get }
@available(iOS 5.0, *)
open var presentingViewController: UIViewController? { get }//当前vc 被哪个vcpresent出来

可以用当前vc或者vc.navigationcontroller的来判断当前vc是否是present出来的