为啥在模态视图控制器被解除后 CAGradientLayer 从视图中删除

Posted

技术标签:

【中文标题】为啥在模态视图控制器被解除后 CAGradientLayer 从视图中删除【英文标题】:Why is the CAGradientLayer removed from view after modal view controller is dismissed为什么在模态视图控制器被解除后 CAGradientLayer 从视图中删除 【发布时间】:2017-04-23 11:38:18 【问题描述】:

我正在创建一个渐变层并将其添加到我的MainViewControllerself.view。

override func viewDidLoad() 
    super.viewDidLoad()

    gradient = CAGradientLayer()
    gradient.frame = view.bounds
    gradient.colors = colors
    view.layer.insertSublayer(gradient, at: 0)


viewDidAppear里面我列举了所有的子层:

override func viewDidAppear(_ animated: Bool) 
    super.viewDidAppear(animated)

    for x in (view.layer.sublayers)! 
        print(x)
    

这是我在运行应用程序时得到的(这是正常的):

<CAGradientLayer: 0x608000224120>
<_UILabelLayer: 0x60000009a400>
<_UILabelLayer: 0x60800009f180>
<CALayer: 0x600000422d60>
<CALayer: 0x608000223820>

然后从MainViewController 我以模态方式呈现另一个vc,然后将其关闭。再次调用此 MainVC viewDidAppear 之后,但这次我得到了这个:

<_UILabelLayer: 0x60000009a400>
<_UILabelLayer: 0x60800009f180>
<CALayer: 0x600000422d60>
<CALayer: 0x608000223820>

CAGradientLayer 已从 self.view 中删除。我可以通过将我的代码从viewDidLoad 移动到viewDidAppear 来解决这个问题,但我想了解为什么在控制器被解散后删除了CAGradientLayer

【问题讨论】:

您在致电super.viewDidAppear(animated)之前尝试过打印吗? 如果我在 viewWillAppear 中打印也会出现同样的问题 你直接继承UIViewController吗? gradient 是如何声明的?你是如何关闭你的模态视图控制器的? @OrkhanAlikhanov:是的,我正在继承 UIViewController 【参考方案1】:

我无法在一个简单的测试程序中重现您的情况。

这里有一些调试建议...

要找出从view.layers 中删除渐变层的位置,请定义

class MyCAGradientLayer: CAGradientLayer 
    deinit 
        print("there it goes")
    

并将您的 CAGradientLayer 替换为在 viewDidLoad 中本地创建的 MyCAGradientLayer

override func viewDidLoad() 
    super.viewDidLoad()

    let gradient = MyCAGradientLayer()
    gradient.frame = view.bounds
    gradient.colors = colors
    view.layer.insertSublayer(gradient, at: 0)

viewDidLoad 完成后,局部变量gradient 将释放它对gradient 的引用,并且只存在一个对gradient 的引用(view.layers 数组中的那个)。

print 语句上设置断点以查看它被释放的位置。

【讨论】:

以上是关于为啥在模态视图控制器被解除后 CAGradientLayer 从视图中删除的主要内容,如果未能解决你的问题,请参考以下文章

UIViewController 在解除先前呈现的模态视图控制器后被释放

当模态视图控制器被解除时如何调用函数

模态转换后解除分配 SKScene

在自定义模式解除转换后,第一个视图控制器的生命周期方法不会被调用

不能连续调用dismissModalViewController吗?

在模态视图控制器的解除动画时访问presentingViewController