उद्देश्य-सी निहित रूपांतरण पूर्णांक चेतावनी के लिए पूर्णांक सटीक 'NSUInteger' (उर्फ 'अहस्ताक्षरित') खो देता है


187

मैं कुछ अभ्यासों के माध्यम से काम कर रहा हूं और एक चेतावनी मिली है जिसमें कहा गया है:

अंतर्निहित रूपांतरण पूर्णांक सटीकता खो देता है: 'NSUInteger' (उर्फ 'अहस्ताक्षरित लंबी') को 'int'

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])
{
    @autoreleasepool {

        NSArray *myColors;

        int i;
        int count;

        myColors = @[@"Red", @"Green", @"Blue", @"Yellow"];

        count = myColors.count; //  <<< issue warning here

        for (i = 0; i < count; i++)

        NSLog (@"Element %i = %@", i, [myColors objectAtIndex: i]);
    }

    return 0;
}

स्क्रीनशॉट

जवाबों:


470

रिटर्न की countविधि ए , और 64-बिट ओएस एक्स प्लेटफॉर्म परNSArrayNSUInteger

  • NSUIntegerके रूप में परिभाषित किया गया है unsigned long, और
  • unsigned long 64-बिट अहस्ताक्षरित पूर्णांक है।
  • int 32-बिट पूर्णांक है।

तो संकलक चेतावनी की intतुलना में "छोटा" डेटाटाइप है NSUInteger

"फाउंडेशन डेटा प्रकार संदर्भ" में NSUInteger भी देखें :

32-बिट अनुप्रयोगों का निर्माण करते समय, NSUInteger एक 32-बिट अहस्ताक्षरित पूर्णांक है। 64-बिट एप्लिकेशन NSUInteger को 64-बिट अहस्ताक्षरित पूर्णांक के रूप में मानता है।

उस संकलक चेतावनी को ठीक करने के लिए, आप या तो स्थानीय countचर को घोषित कर सकते हैं

NSUInteger count;

या (यदि आप सुनिश्चित हैं कि आपके सरणी में 2^31-1तत्वों से अधिक कभी नहीं होगा !), एक स्पष्ट डाली जोड़ें:

int count = (int)[myColors count];

19
बस जोड़ने के लिए - मैंने इस जवाब को वोट दिया क्योंकि मुझे अपने Xcode 5 प्रोजेक्ट में अचानक चेतावनियों और त्रुटियों का भार मिला। आपने 64 बिट का उल्लेख किया है जो मुझे मेरी बिल्ड सेटिंग्स को देखने के लिए प्रेरित करता है। Xcode ने इसे 64 बिट मोड में बदल दिया, जिसमें त्रुटियां थीं। इसे वापस बदलकर arvm7 में बदल दिया गया।
रॉबर्ट जे। क्लेग

1
@Tander 64bit बनाम armv7 संकलन के बीच एक प्रदर्शन अंतर है?
शॉन बुधराम

1
@ShaunBudhram इसे देखते हुए। मैंने कोई अंतर नहीं देखा। यह केवल उन ऐप्स में अंतर करेगा जो सीपीयू का भारी उपयोग करते हैं - उदाहरण के लिए गेम में 64 बिट के लिए संकलन का लाभ दिखाई देगा।
रॉबर्ट जे। क्लेग

7
"1 फरवरी 2015 से, ऐप स्टोर पर अपलोड किए गए नए iOS ऐप में 64-बिट समर्थन शामिल होना चाहिए ..." - ऐप्पल डेवलपर समाचार और अपडेट, 20 अक्टूबर, 2014
पैंग

2
@JayprakashDubey: Apple आपके कंपाइलर की चेतावनियों को नहीं देखता है क्योंकि आप ऐप स्टोर में बाइनरी संकलित एप्लिकेशन सबमिट करते हैं। इसलिए कंपाइलर चेतावनियों के कारण आपके ऐप को अस्वीकार नहीं किया जा सकता है। बेशक आपको अपने ऐप को सही तरीके से काम करने के लिए उन्हें ठीक करना चाहिए।
मार्टिन आर

24

मार्टिन के जवाब के विपरीत, इंट का कास्टिंग (या चेतावनी को अनदेखा करना) हमेशा सुरक्षित नहीं है, भले ही आपको पता हो कि आपके सरणी में 2 ^ 31-1 से अधिक तत्व नहीं हैं। 64-बिट के लिए संकलन करते समय नहीं।

उदाहरण के लिए:

NSArray *array = @[@"a", @"b", @"c"];

int i = (int) [array indexOfObject:@"d"];
// indexOfObject returned NSNotFound, which is NSIntegerMax, which is LONG_MAX in 64 bit.
// We cast this to int and got -1.
// But -1 != NSNotFound. Trouble ahead!

if (i == NSNotFound) {
    // thought we'd get here, but we don't
    NSLog(@"it's not here");
}
else {
    // this is what actually happens
    NSLog(@"it's here: %d", i);

    // **** crash horribly ****
    NSLog(@"the object is %@", array[i]);
}

6
आप सही कह रहे हैं कि नतीजा indexOfObject:देना एक बुरा विचार होगा। मेरा जवाब प्रश्न में विशिष्ट कोड के लिए था, और countविधि वापस नहीं आ सकती है NSNotFound। मैंने आम तौर पर चेतावनी देने या नजरअंदाज करने की सलाह नहीं दी। क्षमा करें यदि वह अस्पष्ट था। वास्तव में आपका नमूना कोड if (i == NSNotFound)64-बिट के लिए संकलित होने पर एक चेतावनी उत्पन्न करेगा , इसलिए समस्या किसी का ध्यान नहीं जाएगी।
मार्टिन आर

@ एड्रियन: अगर आपको कोई आपत्ति नहीं है, तो आप पूछते हैं कि आप क्या करते हैं?
चंद्रमन

@ moonman239 सामान्य तौर पर, यदि संभव हो तो मैं सही प्रकार के चर का उपयोग करूँगा (@ मार्टिन का पहला सुझाव) कास्टिंग के विपरीत (उनका दूसरा)। जैसा कि वह बताते हैं, इस विशेष मामले में कास्टिंग सुरक्षित है, लेकिन मुझे लगता है कि यह एक बुरी आदत है, क्योंकि इसके अप्रत्याशित परिणाम हो सकते हैं (जैसा कि मेरे उदाहरण में है)। मैंने पोस्ट किया क्योंकि मुझे इस विशिष्ट स्थिति से काट दिया गया है (हालाँकि यह == संकलक चेतावनी के बारे में एक अच्छा बिंदु है, जिसे मुझे याद करना चाहिए)।
एड्रियन

2
मुझे लगता है कि गिनती का उपयोग इंडेक्सऑफबजेक्ट की तुलना में कहीं अधिक बार किया जाएगा, और NSInteger के साथ फॉर-लूप को ब्लोटिंग करने के लिए "खराब" कोडिंग शैली नहीं है बकवास है। आपको पूरी तरह से indexOfObject के लिए देखना चाहिए और सुनिश्चित करें कि आप वहां NSIntegers का उपयोग करते हैं, सब कुछ जो बस मायने रखता है कुछ int के रूप में ठीक है, खासकर एक तरीके के फोकस के भीतर
NikkyD

5

प्रोजेक्ट में कुंजी बदलें> सेटिंग सेट करें " टाइप करें कॉल को प्रिंटफ / स्कैनफ : नो "

स्पष्टीकरण: [यह कैसे काम करता है]

यह सुनिश्चित करने के लिए कि प्रिंट किए गए तर्कों में निर्दिष्ट प्रारूप स्ट्रिंग के लिए उपयुक्त प्रकार हैं, और यह कि प्रारूप स्ट्रिंग में निर्दिष्ट रूपांतरणों को समझने के लिए प्रिंटफ और स्कैनफ आदि के लिए कॉल की जाँच करें।

आशा है कि यह काम करेगा

अन्य चेतावनी

उद्देश्य c अंतर्निहित रूपांतरण पूर्णांक सटीक 'NSUInteger' (उर्फ 'अहस्ताक्षरित लंबे') 'int' को खो देता है

कुंजी बदलें " 32 बिट्स> डिबग> * 64 आर्किटेक्चर में निहित रूपांतरण: नहीं "

[ सावधानी: यह 64 बिट्स वास्तुकला रूपांतरण की अन्य चेतावनी को शून्य कर सकता है]


अगर आप अपनी 32 बिट्स लाइब्रेरी को 64 बिट्स में बदलना चाहते हैं, तो यह एक आशाजनक विकल्प है।
सैन

2

एक्सपोजिंग कास्टिंग को "इंट" करने से मेरे मामले में समस्या का समाधान होता है। मेरी भी यही समस्या थी। इसलिए:

int count = (int)[myColors count];

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