2017-02-18 6 views
0

Так что моя функция deinit никогда не вызывается, я уже ищу ответ, но никто из них не работает для меня. И viewcontroller продолжает сбой из-за проблемы с памятью. Спасибо за вашу помощь!Deinit никогда не вызывается, проблема с памятью

Вот мой код:

@IBOutlet weak var scnView: SCNView! 
@IBOutlet weak var artInfoView: UIView! 
@IBOutlet weak var mainTitleLbl: UILabel! 
@IBOutlet weak var textView: UITextView! 
@IBOutlet weak var timeLbl: UILabel! 
@IBOutlet weak var stackView: UIStackView! 
@IBOutlet weak var artistImg: RoundImage! 
@IBOutlet weak var artistNameLbl: UILabel! 
@IBOutlet weak var artistView: UIView! 

var artRoomScene = ArtRoomScene(create: true) 
var artImage = UIImage() 
var artInfo: [Any] = [] 
var posts = [Art]() 
var post: Art! 
var user: Users! 
var showInfo: Bool = false 
var showSimilar: Bool = false 
let alert = Alerts() 

override func viewDidLoad() { 
    super.viewDidLoad() 

    scnView = self.scnView! 
    let scene = artRoomScene 
    scnView.scene = scene 
    scnView.autoenablesDefaultLighting = true 
    scnView.isJitteringEnabled = true 
    scnView.backgroundColor = UIColor.white 


    if let info = self.artInfo[1] as? Art { 
     let image = self.artInfo[0] as? UIImage 
     let height = (image?.size.height)!/900 
     let width = (image?.size.width)!/900 
     self.artRoomScene.setup(artInfo: image, height: height, width: width) 
     self.mainTitleLbl.text = info.title 

     let date = info.postDate/1000 
     let foo: TimeInterval = TimeInterval(date) 
     let theDate = NSDate(timeIntervalSince1970: foo) 
     let time = timeAgoSinceDate(date: theDate as Date, numericDates: true) 
     self.timeLbl.text = "\(time)" 
     self.textView.text = "\(info.artHeight)'H x \(info.artWidth)'W - \(info.price)$/month - \(info.type) \n \(info.description)." 

     DataService.instance.REF_USERS.child("\(info.userUid)").observe(.value, with: { (snapshot) in 
      if let postDict = snapshot.value as? Dictionary<String, AnyObject> { 
       let key = snapshot.key 
       self.user = Users(key: key, artistData: postDict) 

       if let user = self.user { 
        self.artistNameLbl.text = user.name 
        self.artistImg.sd_setImage(with: URL(string: "\(user.profilePicUrl!)") , placeholderImage: UIImage(named:"Placeholder") , options: .continueInBackground) 
       } 
      } 
     }) 
    } 
} 


deinit { 
    print("viewcontroller is being deallocated") 
} 
+0

Что вы пробовали до сих пор, чтобы найти и исправить эту проблему? Каков был результат? Также нет функции 'deinit' в размещенном коде, поэтому, предположительно, вы только разместили часть класса - как вы знаете, проблема в' viewDidLoad() '? –

+0

Потому что, когда я вызываю scnView.removeFromSuperview() в viewDidDisappear, проблема с памятью останавливается. Мой код слишком велик, чтобы опубликовать его все. Я просто обновляю свой вопрос – John

ответ

1

Вам может понадобиться использовать слабый или бесхозный ссылку на self замыканию вы даете вашему DataService. Или вы можете захотеть изучить этот код и убедиться, что он выпустит ссылки на это закрытие, когда вы этого ожидаете. Учитывая глагол observe, я ожидал бы, что он удерживает ссылку на это закрытие на неопределенный срок. Поэтому я рекомендую это:

  1. Используйте слабую ссылку на себя в замыкании
  2. Внутри вашего dealloc или какой-либо другой раз, как viewWillDisappear, скажите DataService, что вы хотите отказаться от подписки/остановки наблюдения. Это важно для того, чтобы у вас не возникала противоположная проблема: свисающий указатель внутри вашего закрытия.

Для # 1, ключ кусок только внутри вашего закрытия, Swift имеет назначенный способ заявить, что self должен быть слабым указателем:

DataService.instance.REF_USERS.child("\(info.userUid)").observe(.value, with: { (snapshot) in 

становится

DataService.instance.REF_USERS.child("\(info.userUid)").observe(.value, with: { [weak self] (snapshot) in 

Примечание что вы также можете использовать [unowned self], но вы утверждаете, что вы знаете, что сам себя никогда не будет не ноль, когда этот блок будет выполняться. Я не думаю, что вы можете знать, что когда вы переходите к третьей стороне. Поэтому используйте [weak self], и тогда вам придется лечить self в качестве дополнительного, что отлично подходит для этого случая!

+0

Привет, спасибо за ответ. Поэтому я попробовал №2, и он работает лучше. Но я действительно не понимаю № 1 (используйте слабое упоминание о себе в закрытии). Не могли бы вы привести мне пример? – John

+0

@John, вы betcha! Ответ обновлен. –

+0

Спасибо @ Крис моя проблема теперь решена. Есть ли другой способ уменьшить память? Любые предложения или статьи? Спасибо. – John

0

Это вызовет ваш Deinit

weak var weakSelf = self 
DataService.instance.REF_USERS.child("\(info.userUid)").observe(.value, with: { (snapshot) in 
    if let postDict = snapshot.value as? Dictionary<String, AnyObject>, let strongSelf = weakSelf { 
     let key = snapshot.key 
     strongSelf.user = Users(key: key, artistData: postDict) 

     if let user = strongSelf.user { 
      strongSelf.artistNameLbl.text = user.name 
       strongSelf.artistImg.sd_setImage(with: URL(string: "\(user.profilePicUrl!)") , placeholderImage: UIImage(named:"Placeholder") , options: .continueInBackground) 
     } 
    } 
}) 
Смежные вопросы