मैंने डीबगर के साथ परीक्षण किया है और दोनों Dictionary और value जिनमें मेरी दिलचस्पी है, शून्य नहीं हैं। जब मैं ऐप Sandbox को सक्षम करता हूं तो ऐप क्रैश हो जाता है, लेकिन जब मैं इसे अक्षम करता हूं तो सब कुछ ठीक काम करता है। Sandbox सक्षम के साथ UserDefaults का उपयोग करते समय क्या कुछ करना है?

कोड जहां दुर्घटना होती है:

func getPreferenceSettings(_ aKey: String) -> Bool
{
  var lastPreferenceSetting: Bool!
  if let currentSetting: Dictionary<String, Bool> = UserDefaults.standard.object(forKey: "defaultValues") as? Dictionary<String,Bool>{
    lastPreferenceSetting = currentSetting[aKey]! //crash at this line
  }else{
    //show error to the user
  }
  return lastPreferenceSetting
}

मैं एक्सकोड 9.4 का उपयोग कर रहा हूं

0
Gianni 20 जुलाई 2018, 19:56
स्पष्ट रूप से currentSettings का कुंजी aKey के लिए कोई मूल्य नहीं है। ! के प्रयोग से बचें और सुरक्षित रूप से खोल दें।
 – 
rmaddy
20 जुलाई 2018, 20:04
lastPreferenceSetting को पूरी तरह से अलिखित Bool घोषित न करें। इस मामले में, यह बेहतर होगा कि इसे प्रारंभिक मूल्य के साथ सामान्य Bool घोषित किया जाए।
 – 
rmaddy
20 जुलाई 2018, 20:05
आपको क्या त्रुटि मिलती है?
 – 
Joakim Danielson
20 जुलाई 2018, 20:57
मैं बूल से वापसी प्रकार के नीचे बदल गया हूँ? जैसा कि शुरू में था और lastPreferenceSetting को वैकल्पिक बनाया क्योंकि मान True या False हो सकता है और मुझे लगता है कि इस मामले में इसे एक डिफ़ॉल्ट मान असाइन करना सही नहीं है, बल्कि फ़ंक्शन के दौरान इसे खोलना है रिटर्न।
 – 
citizen 5
21 जुलाई 2018, 12:23

2 जवाब

आपको जांचना है कि क्या दोनों कुंजियाँ defaultValues और aKey मौजूद हैं। चूंकि वापसी मूल्य गैर-वैकल्पिक वापसी false डिफ़ॉल्ट मान के रूप में है।

यह कोड समर्पित विधि का उपयोग करता है dictionary(forKey

func getPreferenceSettings(_ aKey: String) -> Bool
{
  if let currentSetting = UserDefaults.standard.dictionary(forKey: "defaultValues"),
     let lastPreferenceSetting = currentSetting[aKey] as? Bool {
        return lastPreferenceSetting
  } else {
      //show error to the user
  }
  return false
}
0
vadian 21 जुलाई 2018, 12:33

मुख्य मूल्य शून्य था (मैं डिबग के बजाय रिलीज योजनाओं का उपयोग कर रहा था, इसलिए मैं इसका मूल्य नहीं देख पा रहा था और मान लिया कि यह शून्य नहीं था)। इसके अलावा डिबगर की मदद से मैं यह देखने में सक्षम था कि कुंजी को शब्दकोश में कभी भी सहेजा नहीं गया था। अजीब बात यह है कि Sandbox को अक्षम करने पर क्रैश नहीं होता है। मैंने विधि को निम्नलिखित तरीके से संशोधित किया है, इसलिए यह एक वैकल्पिक देता है और फिर कॉलर optional binding के साथ जांचता है कि कोई कुंजी है या नहीं।

func getPreferenceSettings(_ aKey: String) -> Bool?
{
  var lastPreferenceSetting: Bool?
  if let currentSetting: Dictionary<String, Bool> = UserDefaults.standard.object(forKey: "defaultValues") as? Dictionary<String,Bool>{
    lastPreferenceSetting = currentSetting[aKey]
  }else{
    //show error to the user
  }
  return lastPreferenceSetting
}

संपादित करें

@वादियान

  1. मैं पढ़ रहा था कि ? प्रकार का सही ढंग से उपयोग कब किया जाए और इसका उपयोग आमतौर पर किसी मान की अनुपस्थिति को इंगित करने के लिए किया जाता है उदाहरण के लिए किसी व्यक्ति का मध्य नाम। लेकिन इस मामले में वरीयता संपत्ति हमेशा परियोजना में मौजूद होती है क्योंकि यह डेवलपर द्वारा कठिन कोडित होती है (सिवाय इसके कि मेरे साथ ऐसा हुआ जब मैं इसे UserDefaults में जोड़ना भूल गया और शब्दकोश को अपडेट करने से पहले इसे पहले साफ़ करना पड़ा नई कुंजी के साथ)। अगर मैं सही ढंग से समझता हूं, जो आपने लिखा है, मुझे एक Bool? मान वापस करना चाहिए और फिर optional binding के साथ कॉलर विधि में जांचना चाहिए कि यह nil है या नहीं; यह न केवल उपयोगकर्ता पक्ष के लिए मध्य नाम के मामले के लिए बल्कि डेवलपर पक्ष के लिए भी किया जाना चाहिए क्योंकि एक और डेवलपर हो सकता है जो गलत aKey पास कर सकता है, है ना?

  2. lastPreferenceSetting को ? के रूप में घोषित करना भी सही है, क्योंकि यदि मैं एक डिफ़ॉल्ट मान का उपयोग करता हूं और if let गलत का मूल्यांकन करता है, तो फ़ंक्शन अपेक्षित मान नहीं लौटा सकता है।

0
citizen 5 21 जुलाई 2018, 12:53
इससे कोई फर्क नहीं पड़ता। यदि aKey मौजूद नहीं है या if let का मूल्यांकन false है, तो कोड क्रैश हो जाएगा।
 – 
vadian
21 जुलाई 2018, 12:28
मैंने अपने संदेह और उपरोक्त कोड को अपडेट कर दिया है, आपके समय के लिए धन्यवाद :)
 – 
citizen 5
21 जुलाई 2018, 12:54
आपके संपादन के बाद मेरी टिप्पणी का कोई मतलब नहीं रह गया है। Bool के मामले में एक अनुपस्थित मान को false के रूप में माना जा सकता है, जैसा कि तब होता है जब आप UserDefaults से bool(forKey: के साथ एक Bool मान प्राप्त करते हैं। एक विकल्प (और Apple द्वारा अनुशंसित) सभी डिफ़ॉल्ट मानों का उपयोग करने से पहले उन्हें पंजीकरण करना है।
 – 
vadian
21 जुलाई 2018, 13:02
मेरे मामले में एक अनुपस्थित मान को false के साथ नहीं माना जाना चाहिए क्योंकि मैं संबंधित वरीयता संपत्ति के चेकबॉक्स को अक्षम करने के लिए भी गलत का उपयोग कर रहा हूं। इसके बजाय जब उपयोगकर्ता वरीयता संपत्ति की जांच करता है, तो इसका मूल्य true होगा और कुछ क्रियाएं निष्पादित की जाएंगी। इसलिए यदि कोई शब्दकोश या कुंजी नहीं है तो मुझे यह जांचना चाहिए कि क्या यह मामला है (वैकल्पिक बाध्यकारी के साथ) और यदि ऐसा है तो मुझे किसी भी ऑपरेशन को निष्पादित नहीं करना चाहिए।
 – 
citizen 5
21 जुलाई 2018, 17:15