NSUserDefaults की कुंजी के रूप में एक निरंतर NSString का उपयोग करना


86

मैं उपयोगकर्ता की प्राथमिकताओं को संग्रहीत करने के लिए NSUSerDefaults का उपयोग कर रहा हूं। मुझे याद है कि कहीं न कहीं यह पढ़ता हूं कि कुंजी को स्थिरांक के रूप में स्थापित करना एक अच्छा विचार है - और मैं सहमत हूं। निम्नलिखित कोड वह है जो मेरे पास वर्तमान में है:

[[NSUserDefaults standardUserDefaults]
        setObject:[NSNumber numberWithInt:polygon.numberOfSides] 
           forKey:@"polygonNumberOfSides"];

मैंने इसे बदलने की कोशिश की:

@implementation Controller

NSString const *kPolygonNumberOfSides = @"polygonNumberOfSides";

-(void)savePolygonInfo {
    [[NSUserDefaults standardUserDefaults]
            setObject:[NSNumber numberWithInt:polygon.numberOfSides] 
               forKey:kPolygonNumberOfSides];
}

जबकि यह काम करता है, यह " warning: passing argument 1 of 'objectForKey:' discards qualifiers from pointer target type" पैदा करता है । मैं अपने कोड को कंपाइलर चेतावनियों से मुक्त रखने का इच्छुक हूं। मैं इस चेतावनी को कैसे ठीक कर सकता हूं?

जवाबों:


207

आपको उपयोग करना चाहिए:

NSString * const kPolygonNumberOfSides = @"..."; // const pointer

के बजाय:

NSString const * kPolygonNumberOfSides = @"..."; // pointer to const

पहला NSString ऑब्जेक्ट के लिए एक निरंतर पॉइंटर है, जबकि दूसरा NSString ऑब्जेक्ट के लिए एक पॉइंटर है।

यह एक सूक्ष्म अंतर है। संकलक चेतावनी होती है क्योंकि setObject:forKey:इस प्रकार घोषित किया गया है:

- (void)setObject:(id)value forKey:(NSString *)defaultName;

यह defaultNameतर्क के प्रकार के होने की उम्मीद कर रहा है NSString *। जब आप इसके बजाय एक पॉइंटर को एक स्थिरांक में पास करते हैं, तो आपने इसे कुछ अलग दिया है।

अद्यतन: मैं इंगित करना चाहता हूं कि इन स्थिरांक को परिभाषित किया जाना चाहिए जैसेstaticकि वे केवल एक फ़ाइल के भीतर से उपयोग किए जाने वाले हैं। मैं यह कहता हूं क्योंकि मैंने स्वयं इस समस्या को चलाया है: यदि आप उन्हें स्थिर घोषित नहीं करते हैं, तो वे वैश्विक नामस्थान में मौजूद होंगे, और आप किसी अन्य फ़ाइल में समान नाम के साथ एक चर का उपयोग नहीं कर पाएंगे। देख ऑब्जेक्टिव-सी में स्थिरांक अधिक जानकारी के लिए। उदाहरण के द्वारा समझाने के लिए, यह वर्तमान में मैं उन कुंजियों के लिए उपयोग करता हूं जिन्हें मुझे केवल एक.mफ़ाइलमें उपयोग करने की आवश्यकता है:

static NSString * const kSomeLabel = @"...";

1
NSString * const fooक्योंकि NSStringअपरिवर्तनीय है और सूचक अपरिवर्तनीय है इसलिए यह कभी सही नहीं बदल सकता है? इसके अलावा, मुझे C ++ से याद आता है जो कि constसंक्षेप में static(एक कंपाइलर ऑप्टिमाइज़ेशन) है, इसलिए इसे बाहर करने की आवश्यकता नहीं है। क्या यहाँ भी यही सच है?
टर्नरी

32

constउद्देश्य-सी वस्तुओं के साथ उपयोग न करें , वे वास्तव में इसका उपयोग करने के लिए डिज़ाइन नहीं किए गए थे। NSStringऑब्जेक्ट्स (कई अन्य के बीच) पहले से ही उनके डिजाइन के आधार पर डिफ़ॉल्ट रूप से अपरिवर्तनीय हैं, इसलिए उन्हें बनाते हैंconst बेकार है।

जैसा कि e.James ने सुझाव दिया है , आप एक का उपयोग कर सकते हैं NSString * const, जो कि एक निरंतर सूचक है NSString। यह सूक्ष्म रूप से एक const NSString *(समतुल्य NSString const *) से भिन्न होता है , जो एक स्थिरांक का सूचक है NSString। एक का उपयोग करना NSString * constफिर नियत करने से रोकता है kPolyएक नया करने के लिए बात करने के लिए NSStringवस्तु।


कास्ट के उपयोग के बारे में अच्छी बात। इसीलिए बहुत से Objective-C classes में "Mutable" वेरिएंट होते हैं।
ई.जेम्स

2
मैंने सोचा था कि constइसका मतलब यह भी है कि आप इसे दोबारा नहीं दे सकते। मुझे लगता है कि मेरे पास गलत था।
डैन रोसेनस्टार्क

18

अन्य वर्गों से पहुंच के लिए:

extern NSString * const PolygonNumberOfSidesPrefsKey;

।म

NSString * const PolygonNumberOfSidesPrefsKey = @"PolygonNumberOfSides"

केवल वर्तमान वर्ग के अंदर पहुंच के लिए:

।म

static NSString * const kPolygonNumberOfSidesPrefsKey = @"PolygonNumberOfSides"

5

मैं यहां तक ​​कि निरंतर अधिक वर्णनात्मक बनाने का सुझाव दूंगा। बहुभुज के पक्षों की संख्या के लिए एक स्थिरांक कहीं से भी आ सकता है। एक सुझाव के रूप में, कैसे के बारे में:

kDefaultsPolygonNumberOfSides;

बजाय।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.