2016-10-27 6 views
0

Я имею дело с некоторой проблемой освобождения и, возможно, сильной или круговой ссылкой, которая не может понять. Я три UIView с инстанцированием, как показано ниже:Сильные ссылки и проблемы с памятью UIView

Существует один главный ViewController, который я добавил UIView внутри него в раскадровке и UIView имеет weak выходное отверстие внутри класса, как:

class ViewController : UIViewController { 

    //MARK: - outlets 
    @IBOutlet weak var firstView: FirstUiview! 

} 

второго UIView является добавлен как подвид на первый взгляд программно нравится:

class FirstUiview : UIView { 

     //creating an instance of secondUiView 
     lazy var mySecondView: SecondViewClass = { 
      let dv = SecondViewClass() 
      dv.backgroundColor = UIColor.red 
      return dv 
     }() 


     //sometime later by clicking on a button 
     self.addSubview(mySecondView) 

     //a button will be tapped to remove mySecondView; 
     //later will be called at some point upon tapping: 

     func removingSecondViewByTapping() { 
     if mySecondView.isDescendant(of: self) { 
      mySecondView.removeFromSuperview() 
     } 
     } 

} 

Теперь SecondViewClass:

class SecondViewClass : UIView { 

     //in this class I create bunch of uiview objects like below: 
     lazy var aView : UIView = { 
     let hl = UIView() 
     hl.tag = 0 
     hl.backgroundColor = UIColor.lightGray 
     return hl 
     }() 

     self.addSubview(aView) //... this goes on and I add other similar views the same way. 

     //creating an instance of thirdView 
     var let thirdView = UIView() 
     self.addSubview(thirdView) 

} 

Теперь, если пользователь нажимает на кнопку, чтобы удалить mySecondView, а затем снова добавить его в другое время (все в том же ViewController) Я ожидаю, что все подвиды из mySecondView были освобождены и ушли, но они все там. Я был бы очень признателен, если бы кто-нибудь мог указать мне на него, где я держу сильную ссылку или если есть круговая проблема ссылок? или что-то еще?

+0

Почему вы ожидали бы подвидов 2-го зрения на уйти? Удаление 'mySecondView' из своего супервизора не позволяет удалить все его подпрограммы из себя. – dan

+0

@dan Ой, подождите, я подумал, что view.removeFromSuperview выпустит и уничтожит представление, включая его subviews, если его subviews не ссылаются на что-то, что удерживается, не так ли? если нет, не могли бы вы посоветовать мне, как я могу полностью удалить отправку представления, включая его подзаголовки? – TheeBen

ответ

4

У вас есть две прочные ссылки на ваши представления, ваше настраиваемое свойство и ссылка на иерархию представлений, установленную при вызове addSubview. Когда вы удаляете представление из иерархии представления, ваш класс сам по-прежнему имеет свою сильную ссылку на него.

Вы можете решить эту проблему, сделав свою ссылку опцией, а когда вы позвоните removeFromSuperview, также вручную установите свою ссылку на nil. Или, может быть, проще, вы можете решить эту проблему, используя ссылки weak, позволяя иерархии представлений поддерживать сильные ссылки для вас. И потому, что ваш заказ свойство weak, при удалении его из иерархии представлений (таким образом, устраняя только сильные ссылки на него), ваш weak ссылка автоматически станет nil:

class FirstView: UIView { 

    weak var secondView: SecondView?  // note the `weak` reference, which is obviously an optional 

    //sometime later by clicking on a button 

    func doSomething() { 
     let subview = SecondView() 
     subview.backgroundColor = .red 
     self.addSubview(subview) 
     secondView = subview 
    } 

    // a button will be tapped to remove secondView; 
    // later will be called at some point upon tapping ... 

    func removingSecondViewByTapping() { 
     secondView?.removeFromSuperview() 
    } 
} 
+0

Спасибо за ваш ответ. Это действительно похоже на правильное объяснение и ответ. Боюсь, что проблема глубже, чем для меня, поскольку я пытался упростить ее здесь. Очень ясный ответ, хотя! Я пробовал это без блокировки. У моего третьего представления есть протокол, соответствующий родительскому виду, может быть, это еще одна проблема? Я убедился, что это слабый делегат протокола, т. Е. Что-то вроде http://stackoverflow.com/a/24104371/5601401 – TheeBen

+0

Да, отказ от использования слабых протоколов также может быть проблемой. Таким образом, если вы исправили вышеизложенное и также убедились, что используете ссылки «слабых» делегатов, и вы все еще не видите, что ваши взгляды освобождены, вам необходимо определить, что поддерживает сильная ссылка. Использование «Графа памяти отладки» (см. Http://stackoverflow.com/a/30993476/1271826) может быть полезно для отслеживания любых дополнительных проблем, которые могут возникнуть. – Rob