2017-05-12 12 views
8

नहीं बुलाया हो रही Deinit मैं एक UIView एक आप नीचे देख सकते करने के लिए इसी तरह की है:आईओएस अधिसूचना पर्यवेक्षक को हटाने में असमर्थ।

class ViewTaskViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { 
override func viewDidLoad() { 
    super.viewDidLoad() 
    subscribeToNotifications() 
} 

func subscribeToNotifications() { 
    let notification = NotificationCenter.default 
    notification.addObserver(forName: Notification.Name(rawValue: "TimerUpdated"), object: nil, queue: nil, using: handleUpdateTimer) 
    print("Subscribed to NotificationCenter in ViewTaskViewController") 
} 

override func viewWillDisappear(_ animated: Bool) { 
    super.viewWillDisappear(animated) 
    print("TUFU TUFU TUFU") 
    NotificationCenter.default.removeObserver(self) 
} 

deinit { 
    print("DENINT") 
} 

@objc func handleUpdateTimer(notification: Notification) { 
    if let userInfo = notification.userInfo, let timeInSeconds = userInfo["timeInSeconds"] as? Int { 

     withUnsafePointer(to: &self.view) { 
      print("We got timeeeeee \(timeInSeconds) \($0)") 
     } 

     //do something here.... 
    } 
} 

}

मुद्दा मैं कर रहा हूँ है कि मैं इस विशेष UIView जब से पर्यवेक्षकों को दूर करने में असमर्थ हूँ उपयोगकर्ता बैक बटन हिट करता है और दूसरे व्यू कंट्रोलर पर लौटता है।

ViewWillDisppear कहा जाता है लेकिन deinit नहीं कहा जाता है। अजीब बात यह है कि अगर हम subscribeToNotifications() को viewDidLoad() से हटाते हैं तो deinit कहा जाता है।

अन्य मुद्दा स्मृति रिसाव से संबंधित है। जैसा कि आप नीचे दिए गए स्क्रीनशॉट में देख सकते हैं, जब दृश्य अधिसूचनाओं की सदस्यता लेता है और उपयोगकर्ता दृश्य को फिर से दर्ज/पुनः प्रविष्ट करता है, तो स्मृति उपयोग बढ़ता है। enter image description here

अब तुलना करें कि subscribeToNotifications() पर टिप्पणी की गई है, स्मृति उपयोग में कोई वृद्धि नहीं है और दृश्य नियंत्रक का केवल एक उदाहरण है। enter image description here निष्कर्ष यह है कि UIView के नए उदाहरण की अधिसूचना सदस्यता निर्माण के बीच एक सहसंबंध है, इसलिए deinit नहीं कहा जा रहा है।

मैं यह जानना चाहता हूं कि कोई तरीका है कि हम दृश्य को पूर्वनिर्धारित कर सकते हैं और अधिसूचना से सदस्यता समाप्त कर सकते हैं।

अगर आपको और जानकारी चाहिए तो कृपया मुझे बताएं। :)

+0

आप जो 'addObserver' विधि का उपयोग कर रहे हैं, उसके लिए दस्तावेज़ीकरण कहता है, "अवलोकनों को अनधिकृत करने के लिए, आप ओब्सर्वर (_ :)।" को हटाने के लिए ** इस विधि द्वारा लौटा ** ऑब्जेक्ट पास करते हैं। इसके बजाए, आप मानते हैं कि 'स्वयं' पंजीकृत वस्तु है। –

उत्तर

4

मैं) removeObserver (मिल गया है तभी काम करता है आप addObserver() के इस संस्करण का उपयोग

notification.addObserver(self, selector:#selector(self.handleUpdateTimer), name: Notification.Name(rawValue: "TimerUpdated"), object: nil) 

मैं मूल संस्करण आप वास्तव में यह दर्शाता है नहीं कर रहे हैं, जो पर्यवेक्षक है साथ अनुमान लगा रहा हूँ ।

+0

इसके लिए बहुत बहुत धन्यवाद! मैंने पहले से ही कोशिश की थी कि खालिद ने क्या सुझाव दिया था लेकिन अभी भी इसे पर्यवेक्षक को नहीं हटा रहा था। लेकिन आपकी विधि निश्चित रूप से इस मुद्दे को हल करने और हल करने में मदद करती है! :) –

1

रूप @Spads कहा कि तुम

NotificationCenter.default.addObserver(self, selector: #selector(subscribeToNotifications), name: NSNotification.Name(rawValue: "TimerUpdate"), object: nil) 

या पहले से है उपयोग कर सकते हैं। आप इसे के नाम से अपनी सूचना को हटा सकते हैं या इसे संदर्भ

NotificationCenter.default.removeObserver(self, name: "TimerUpdate", object: nil) 

अगर आप अपने वर्ग के शीर्ष पर अपनी सूचना घोषित तो आप सीधे पारित कर सकते हैं अपनी सूचना के संदर्भ आपके मामले में हटा दिया जाना चाहिए है अधिसूचना

NotificationCenter.default.removeObserver(notification) 
+0

तो मैंने इस सवाल को सबमिट करने से पहले भी कोशिश की और इसे काम नहीं किया, हालांकि पर्यवेक्षक को जोड़ने की दूसरी विधि चाल चल रही है! :) धन्यवाद –

संबंधित मुद्दे