2015-11-19 13 views
6

जब मैं एक UIAlertController सुविधा प्रारंभकर्ता को परिभाषित:विस्तार UIAlertController सुविधा init चेतावनी

extension UIAlertController { 
    convenience init(message: String?) { 
     self.init(title: nil, message: message, preferredStyle: .Alert) 
     self.addAction(UIAlertAction(title: "OK", style: .Cancel, handler: nil)) 
    } 
} 

और UIViewController की मेरी उपवर्ग में एक बटन कार्रवाई में इसका इस्तेमाल करते हैं:

func buttonAction(button: UIButton) { 
    let alert = UIAlertController(dictionary: nil, error: nil, handler: nil) 
    presentViewController(alert, animated: true, completion: nil) 
} 

और सिम्युलेटर पर कि बटन पर क्लिक करें , मुझे चेतावनी मिलती है:

दृश्य नियंत्रक के दृश्य को लोड करने का प्रयास

func UIAlertControllerWithDictionary(message: String?) -> UIAlertController { 
    let alert = UIAlertController(title: nil, message: message, preferredStyle: .Alert) 
    alert.addAction(UIAlertAction(title: "OK", style: .Cancel, handler: nil)) 
    return alert 
} 
: le यह deallocating है की अनुमति नहीं है और अपरिभाषित व्यवहार में हो सकता है (UIAlertController)

हालांकि, मैं अगर एक सुविधा प्रारंभकर्ता के बजाय एक चेतावनी प्राप्त नहीं है, मैं एक वैश्विक फ़ंक्शन का उपयोग करें

मैंने ऐप्पल को आईओएस एसडीके बग के रूप में इसकी सूचना दी है।

यह तय होने तक, चेतावनी को अनदेखा करना और सुविधा प्रारंभकर्ता का उपयोग करना ठीक है?

उत्तर

10

अपने ViewController में इस विधि मैं सुविधा initializers के साथ एक ही मुद्दा देखा। यह वास्तव में एक बार में दो बग है।

  1. स्विफ्ट UIAlertController उदाहरण आवंटित करता है।
  2. स्विफ्ट स्विफ्ट द्वारा बनाई गई घटना के साथ आपकी सुविधा init कॉल करता है।
  3. वहां आप UIKit की सुविधा init कहते हैं, जो वास्तव में उद्देश्य-सी फैक्ट्री विधि +(id) alertControllerWithTitle:message:preferredStyle: है।
  4. वहां UIKit अपना UIAlertController उदाहरण आवंटित करता है। (बग # 1)
  5. UIKit अपना स्वयं का उदाहरण सेट करता है।
  6. UIKit आपके स्विफ्ट इंस्टेंस को हटा देता है।
  7. UIAlertControllerdeinit (dealloc) view संपत्ति का उपयोग करता है जो लॉग संदेश की ओर जाता है। (बग # 2)
  8. नियंत्रण आपकी अपनी सुविधा सुविधा पर वापस आता है जहां self चुपचाप स्विफ्ट के UIAlertController उदाहरण से यूआईकिट से एक में बदल गया।
  9. जो कुछ भी आप करते हैं वह अब UIKit द्वारा बनाए गए उदाहरण पर होता है जो ठीक है।

तो पहली बग यह है कि स्विफ्ट एक अस्थायी UIAlertController बनाता है जिसे कभी भी इस्तेमाल किए बिना नष्ट किया जाता है।

दूसरी बग यह है कि UIViewControllerview संपत्ति को डीनाइजलाइजेशन के दौरान एक्सेस करता है, जो इसे नहीं करना चाहिए।


अपने प्रश्न के बारे में:
दोनों कीड़े तो हम बस अब के लिए चेतावनी को अनदेखा कर सकते हैं समस्याग्रस्त नहीं होना चाहिए। मैं भी ऐसा करता हूं और अभी तक कोई समस्या नहीं थी - बस लॉग में चेतावनी।

+0

वाह पर अनुरोध को आगे बढ़ाता है। उत्कृष्ट डिबगिंग कौशल! आप ये सब कैसे जानते हो? क्या आपने बस एक्सकोड डीबगर का उपयोग किया है, ब्रेकपॉइंट सेट किया है, और चरणबद्ध है? – ma11hew28

+1

अनुभव का मिश्रण, उद्देश्य-सी रनटाइम का ज्ञान और हां, डिबगिंग :) – fluidsonic

3

मैं भी यही मुद्दा

का सामना करना पड़ा एक दृश्य नियंत्रक यह deallocating है की अनुमति नहीं है और अपरिभाषित व्यवहार में हो सकता है, जबकि (UIAlertController)

तो मैं ले जाया गया को देखते लोड करने के प्रयास इसके लिए वैकल्पिक तरीके से।

import UIKit 
import Foundation 

//the show alert function for failure 
func showAlertforNetworkFailure(alerttitle :String, alertmessage: String,ButtonTitle: String, viewController: UIViewController) 
{ 


    let alertController = UIAlertController(title: alerttitle, message: alertmessage, preferredStyle: .Alert) 
    let okButtonOnAlertAction = UIAlertAction(title: ButtonTitle, style: .Default) 
     { (action) -> Void in 
      //what happens when "ok" is pressed 

    } 
    alertController.addAction(okButtonOnAlertAction) 
    alertController.show() 



} 

// function for show alert in Main View Controller 
extension UIAlertController { 

    func show() { 
     present(true, completion: nil) 
    } 

    func present(animated: Bool, completion: (() -> Void)?) { 
     if let rootVC = UIApplication.sharedApplication().keyWindow?.rootViewController { 
      presentFromController(rootVC, animated: animated, completion: completion) 
     } 
    } 

    private func presentFromController(controller: UIViewController, animated: Bool, completion: (() -> Void)?) { 
     if let navVC = controller as? UINavigationController, 
      let visibleVC = navVC.visibleViewController { 
       presentFromController(visibleVC, animated: animated, completion: completion) 
     } else { 
       controller.presentViewController(self, animated: animated, completion: completion); 
     } 
    } 
} 

कॉल के रूप में

showAlertforNetworkFailure("Server Error!!!", alertmessage: "Server does not responding,please Try in later.", ButtonTitle: "Okay", viewController: self) 
+0

दिलचस्प जवाब। धन्यवाद। :-) मैं अपनी सुविधा प्रारंभकर्ता पसंद करता हूं क्योंकि यह कम कोड है और 'समापन' हैंडलर का खुलासा करता है। – ma11hew28

+0

@MattDiPasquale - मेरे बहुत वरिष्ठ tanx .... –

+0

आप UIViewController के दस्तावेज़ से, शीर्ष दृश्य नियंत्रक या नहीं, चिंता करने के बिना वर्तमान दृश्य कंट्रोलर को बस कॉल करने में सक्षम होना चाहिए: जिस ऑब्जेक्ट पर आप इस विधि को कॉल करते हैं प्रस्तुति को संभालने वाला हमेशा ऐसा नहीं हो सकता है। प्रत्येक प्रस्तुति शैली में अपने व्यवहार को नियंत्रित करने वाले विभिन्न नियम होते हैं। उदाहरण के लिए, एक पूर्ण-स्क्रीन प्रेजेंटेशन को व्यू कंट्रोलर द्वारा किया जाना चाहिए ..... यदि वर्तमान व्यू कंट्रोलर अनुरोध पूरा करने में असमर्थ है, तो यह दृश्य नियंत्रक पदानुक्रम को अपने निकटतम माता-पिता –

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