प्रारूप तर्क के रूप में उपयोग किए जाने पर NSInteger चर को लंबे समय तक क्यों डालना पड़ता है?


143
NSInteger myInt = 1804809223;
NSLog(@"%i", myInt); <==== 

उपरोक्त कोड एक त्रुटि पैदा करता है:

प्रकार 'NSInteger' के मानों का उपयोग प्रारूप तर्क के रूप में नहीं किया जाना चाहिए; इसके बजाय एक स्पष्ट कलाकारों को 'लंबे' में जोड़ें

सही NSLogसंदेश वास्तव में है NSLog(@"%lg", (long) myInt);। मैं क्यों की पूर्णांक मान परिवर्तित करने के लिए क्या myIntकरने के लिए longअगर मैं प्रदर्शित करने के लिए मूल्य चाहते हैं?


1
@ डैनियलली, यदि आप उपयोग करते हैं NSLog(@"%ld", (long) myInt);, तो longकास्ट को lक्वालिफायर के साथ मैच करना होता है %ld, लेकिन यह सब अनावश्यक है जैसा NSLog(@"%d", myInt);कि पर्याप्त है (यह देखते हुए कि हम myIntनहीं देख सकते हैं long। नीचे की रेखा, myIntयदि आप प्रारूप में लंबे समय तक क्वालीफायर का उपयोग कर रहे हैं)। स्ट्रिंग, लेकिन यहां लंबे स्ट्रिंग प्रारूप वाले क्वालीफायर या longकास्ट का उपयोग करने की कोई आवश्यकता नहीं है।
रोब

1
जाहिर है, यह सच नहीं है कि NSLog (@ "% i", myInt); पर्याप्त है क्योंकि आपको त्रुटि संदेश मिलेगा जैसा कि मैंने ऊपर दिखाया है।
डैनियल ली

2
@DanielLee मार्टिन आर की टिप्पणी देखें। आपने अपना प्रश्न iOS टैग (जहां लंबे समय तक नहीं है ) के साथ पोस्ट किया NSIntegerहै , लेकिन ऐसा लगता है कि आप ओएस एक्स लक्ष्य (जहां है ) के साथ संकलन कर रहे हैं । NSInteger long
रॉब

हाँ! मैंने देखा। मुझे नहीं पता था कि iOS और OSX NSInteger को बिट और टाइप में अलग बना देगा।
डैनियल ली

जवाबों:


193

यदि आप OS X (64-बिट) पर संकलित करते हैं, तो आपको यह चेतावनी मिलती है, क्योंकि उस प्लेटफॉर्म NSIntegerको long64-बिट पूर्णांक के रूप में परिभाषित किया गया है। %iप्रारूप, दूसरे हाथ पर, के लिए है intजो 32-बिट है। तो प्रारूप और वास्तविक पैरामीटर आकार में मेल नहीं खाते हैं।

चूंकि NSInteger32-बिट या 64-बिट है, प्लेटफॉर्म के आधार पर, कंपाइलर longआमतौर पर एक कास्ट को जोड़ने की सलाह देता है ।

अपडेट: चूंकि iOS 7 अब 64-बिट का समर्थन करता है, इसलिए iOS के लिए कंप्लेन करने पर आपको वही चेतावनी मिल सकती है।


1
मुझे आईओएस 7 पर यह त्रुटि मिलती है। चूंकि केवल नवीनतम आईफोन 5 एस 64 बिट है, अगर मैं इसे सेट करता हूं तो यह पुराने 32 जीबी डिवाइस पर कोई समस्या पैदा करेगा?
प्रितेश देसाई

25
@BartSimpson: एक स्पष्ट मामले के साथ "लंबा", जैसा कि NSLog(@"%ld", (long) myInt), यह 32-बिट और 64-बिट पर सही ढंग से काम करता है।
मार्टिन आर

@MartinR अगर हम कास्टिंग कर रहे हैं, तो सिर्फ पहली जगह में लंबे समय तक इस्तेमाल क्यों न करें?
विलियम एंट्रीकेन

3
@FullDecent: निश्चित रूप से आप यहां लंबे समय तक काम कर सकते हैं long myInt = [myNumber longValue];:। लेकिन कई (कोर) फाउंडेशन तरीके एनएस (यू) इंटेगर को पैरामीटर या रिटर्न वैल्यू के रूप में उपयोग करते हैं, इसलिए सामान्य समस्या बनी हुई है। साथ ही यह आपके ऐप में 64-बिट डिवाइस पर एक बड़ी उपलब्ध रेंज प्राप्त करने के लिए NS (U) इंटेगर का उपयोग करने के लिए समझ में आता है।
मार्टिन आर

39

यदि आपका प्रारूप निर्दिष्टकर्ता आपके डेटा प्रकारों से मेल खाता है, तो आपको कुछ भी करने की आवश्यकता नहीं है। NSIntegerदेशी प्रकारों के संदर्भ में कैसे परिभाषित किया गया है , इसके विवरण के लिए मार्टिन आर का उत्तर देखें ।

तो 64-बिट वातावरण के लिए बनाए जाने वाले कोड के लिए, आप अपने लॉग स्टेटमेंट को इस तरह लिख सकते हैं:

NSLog(@"%ld",  myInt); 

जबकि 32-बिट वातावरण के लिए आप लिख सकते हैं:

NSLog(@"%d",  myInt); 

और यह सभी जाति के बिना काम करेगा।

वैसे भी कास्ट का उपयोग करने का एक कारण यह है कि अच्छा कोड प्लेटफॉर्म पर पोर्ट किया जा सकता है, और यदि आप अपने चर को स्पष्ट रूप से रखते हैं तो यह 32 और 64 बिट दोनों पर साफ-साफ संकलन करेगा:

NSLog(@"%ld",  (long)myInt);

और ध्यान दें कि यह केवल NSLog कथनों के लिए नहीं है, जो कि सभी के बाद सिर्फ डिबगिंग एड्स हैं, बल्कि [NSString stringWithFormat:]विभिन्न व्युत्पन्न संदेशों के लिए भी हैं, जो उत्पादन कोड के वैध तत्व हैं।


1
तो अब जब इस हैक की आवश्यकता है, क्या अभी भी पहली जगह में NSInteger का उपयोग करना सबसे अच्छा अभ्यास है?
विलियम एंट्रीकेन

@FullDecent यह केवल कोड में एक समस्या है जिसे रनटाइम की व्याख्या की जाती है, जैसे प्रारूप स्ट्रिंग। अल संकलित कोड NSInteger typedef का लाभ उठाता है।
मोनोलो

यह है NSInteger उपयोग करने के लिए सबसे अच्छा अभ्यास है, क्योंकि वहाँ अच्छे कारणों क्यों यह जिस तरह से यह परिभाषित किया गया है परिभाषित किया गया है कर रहे हैं।
gnasher729

22

NSLog में NSInteger पास करने के बजाय, बस एक NSNumber पास करें। यह सभी जातियों के आसपास मिलेगा और सही स्ट्रिंग प्रारूप विनिर्देशक का चयन करेगा।

NSNumber foo = @9000;
NSLog(@"foo: %@", foo);
NSInteger bar = 9001;
NSLog(@"bar: %@", @(bar));

यह भी NSUIntegers के लिए काम करता है कि इसके बारे में चिंता किए बिना। मिश्रित 64 बिट / 32 बिट परिवेश में NSInteger और NSUInteger का उत्तर देखें


2
मुझे लगता है कि चयनित उत्तर तकनीकी रूप से सवाल का सबसे अच्छा जवाब है, लेकिन अगर आप जानना चाहते हैं कि प्रत्येक घटना को कैसे रोका जाए और चेतावनी को कैसे रोका जाए तो मुझे लगता है कि यह सबसे अच्छा समाधान है।
डैनियल वुड

0

यह उपयोग करते समय चेतावनी देता रहता है NSLog(@"%ld", (long)myInt);, लेकिन long myInt = 1804809223;iOS 10 में परिवर्तन की घोषणा के बाद चेतावनी देना बंद कर देता है ।


-2

ओएस एक्स 32- और 64-बिट वातावरण में मूल्यों का प्रतिनिधित्व करने का एक सुसंगत साधन प्रदान करने के लिए कई डेटा प्रकारों- NSInteger, NSUInteger, CGFloat, और CFIndex- का उपयोग करता है। 32-बिट वातावरण में, NSInteger और NSUInteger को क्रमशः अंतर और अहस्ताक्षरित int के रूप में परिभाषित किया गया है। 64-बिट वातावरण में, NSInteger और NSUInteger को क्रमशः लंबा और अहस्ताक्षरित रूप में परिभाषित किया गया है। प्लेटफ़ॉर्म के आधार पर अलग-अलग प्रिंटफ-स्टाइल प्रकार के स्पेसर का उपयोग करने की आवश्यकता से बचने के लिए, आप इस लिंक में दिखाए गए स्पेसियर का उपयोग 32 बिट और 64 बिट वातावरण दोनों के लिए कर सकते हैं ।

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