2017-02-18 30 views
0

所以我的deinit func永遠不會被調用,我已經在尋找一個答案,但它們都不適合我。由於內存問題,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

因爲當我在viewDidDisappear中調用scnView.removeFromSuperview()時,內存問題停止。我的代碼太大而無法發佈。我只是更新我的問題 – John

回答

1

您可能需要您給您的DataService封閉使用弱或無主參考self。或者,您可能希望查看該代碼,並確保它在您期望的時候釋放它對此閉包的引用。鑑於observe動詞,我期望它無限期地持有這個閉包的參考。因此,我建議這樣的:

  1. 使用弱引用自己在封閉
  2. 裏面你的dealloc,或者一些其他的時間像viewWillDisappear,告訴您想退訂/停止觀察DataService的。這很重要,這樣您就不會遇到相反的問題:來自閉包內部的懸掛指針。

#1的關鍵棋子就是你的瓶蓋內,斯威夫特有一個指定的方式來聲明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],但是你會斷言你知道當這個模塊執行時,self不會是非零的。當你傳遞給第三方時,我不認爲你可以知道。所以使用[weak self],然後你必須把self作爲一個可選項,這對於這種情況非常有用!

+0

嗨,謝謝你的答案。所以我嘗試了#2,並且知道它工作得更好。但我真的不明白#1(在閉包中使用弱自引)。你能舉個例子嗎? – John

+0

@John,你好!答案已更新。 –

+0

謝謝@Chris我的問題現在已解決。有其他方式可以減少記憶嗎?任何建議或文章?謝謝。 – 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) 
     } 
    } 
}) 
相關問題