Reputation: 839
So my deinit func never get called, I've already search for an answer, but none of them works for me. And the viewcontroller keep crashing because of memory issue. Thanks for your help!
Here's my code:
@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")
}
Upvotes: 0
Views: 198
Reputation: 18290
You may need to use a weak or unowned reference to self
in the closure you are giving to your DataService. Or, you may want to look into that code and make sure that it releases it's references to this closure when you expect it to. Given the observe
verb, I would expect that it holds the reference to this closure indefinitely. So I recommend this:
For #1, the key piece is just inside your closure, Swift has a designated way to declare that self
should be a weak pointer:
DataService.instance.REF_USERS.child("\(info.userUid)").observe(.value, with: { (snapshot) in
becomes
DataService.instance.REF_USERS.child("\(info.userUid)").observe(.value, with: { [weak self] (snapshot) in
Note that you could also use [unowned self]
, but you would be asserting that you know self will never be non-nil when this block executes. I don't think you can know that when you're passing to a 3rd party. So use [weak self]
and then you'll have to treat self
as an optional, which is great for this case!
Upvotes: 1
Reputation: 1069
This will call your 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)
}
}
})
Upvotes: 0