2013-10-15 20 views
19

वृक्षारोपण पर एक ट्यूटोरियल के बाद, मुझे एक्सकोड में यह लोकप्रिय ऑब्जेक्ट-सी चेतावनी संदेश दिखाई देता है।उद्देश्य सी निहित रूपांतरण पूर्णांक सटीक खो देता है 'NSUInteger'

मेरे बटन समारोह

- (IBAction)buttonPressed:(UIButton *)sender { 
    NSUInteger index = arc4random_uniform(predictionArray.count); 
    self.predictionLabel.text = [predictionArray objectAtIndex:index]; 
} 

मैं NSUInteger लाइन पर इसे देख, मैं कुछ इसी तरह की stackoverflows के कुछ ही किए हैं और उनका 32 बिट बनाम 64 बिट संख्या और प्रकार के कास्टिंग के बारे में बात करने लगते हैं, लेकिन यकीन नहीं कैसे ऐसा करने के लिए यहाँ?

मेरे predictionArray

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    predictionArray = [[NSArray alloc] initWithObjects: 
        @"It is certain", @"It is decidely so", @"All signs say YES", @"The stars are not aligned", 
        @"My reply is no", 
        @"It is doubtful", 
        @"Better not tell you now", 
        @"Concentrate and ask again", 
        @"Unable to answer now", nil]; 
// Do any additional setup after loading the view, typically from a nib. 
} 

enter image description here

उत्तर

67

आप सुरक्षित रूप से एक कलाकारों के साथ चेतावनी को दबाने कर सकते हैं।

NSUInteger index = arc4random_uniform((uint32_t) predictionArray.count); 

यह हमेशा सुरक्षित चेतावनी को दबाने के लिए है, तो चीजें चेतावनी से छुटकारा पाने के कास्टिंग मत जाओ जब तक आप पता लगाएँ कि क्या आपरेशन सुरक्षित है समझ नहीं है।

यहां क्या हो रहा है यह है कि NSUInteger आपके प्लेटफ़ॉर्म पर 64-बिट पूर्णांक प्रकार के लिए टाइपिफ़ है। यह हमेशा 64 बिट्स नहीं है, बस कुछ प्लेटफ़ॉर्म पर। संकलक आपको चेतावनी दे रहा है कि उनमें से कुछ बिट्स फेंक रहे हैं। यदि आप जानते हैं कि ये बिट्स महत्वहीन हैं, तो आप केवल एक कास्ट का उपयोग कर सकते हैं।

इस मामले में, परिणाम यह है कि index हमेशा 2 -1 के तहत होगा। यदि यह predictionArray के लिए 2 या अधिक तत्वों के लिए भी दूरस्थ रूप से संभव है, तो आपके प्रोग्राम में कोई त्रुटि है और आपको arc4random_uniform() का 64-बिट संस्करण बनाना होगा। आप नीचे दिए गए कोड के साथ यह सुनिश्चित कर सकते हैं:

assert(predictionArray.count <= (uint32_t) -1); 
+0

हम्म, मैंने अभी यह कोशिश की, लेकिन फिर भी वही चेतावनी। तो मैं NSUInteger को किस तरह कास्टिंग कर रहा हूं? '(NSUInteger) का अर्थ क्या है। या शायद अधिक महत्वपूर्ण बात यह है कि यह मुझे किस बारे में चेतावनी दे रहा है? –

+0

@LeonGaban: मैंने कास्ट को गलत जगह पर रखा है। –

+0

धन्यवाद! अभी भी इसे समझने की कोशिश कर रहे हैं, इसलिए 'NSUInteger' हमेशा 32 बिट int है? मैंने इसे 64 बिट के रूप में डालने की कोशिश की और मुझे एक ही त्रुटि मिली। उस बिट चीज मेरे लिए नई है, –

11

मेरी टिप्पणी के अनुसार, arc4random_uniform() एक u_int32_t, एक अहस्ताक्षरित पूर्णांक हमेशा 32 बिट है कि, लक्ष्य वास्तुकला की परवाह किए बिना में लेता है, और रिटर्न,। हालांकि, predictionArray.count एक NSUInteger देता है, जो 32-बिट और 64-बिट सिस्टम के लिए typedef डी अलग-अलग है; 32-बिट सिस्टम पर 32 बिट्स (unsigned int) और 64-बिट सिस्टम पर 64-बिट्स (unsigned long) है। यदि आप 64-बिट सिस्टम पर चल रहे हैं, तो 64-बिट NSUInteger में 32-बिट पूर्णांक की अपेक्षा रखने वाले फ़ंक्शन में गुजरने के लिए संकलक यह शिकायत करेगा कि आप बिट्स को फेंक रहे हैं।

+0

स्पष्टीकरण के लिए धन्यवाद, इसलिए यदि मैं 64 बिट फ़ंक्शन/विधि में 32 बिट नंबर भेजता हूं तो क्या प्रोग्राम धीमा हो जाता है? या यह सिर्फ यह कह रहा है कि मैं और अधिक कुशल हो सकता हूं। क्या 'arc4random_uniform()' का 64 बिट संस्करण है? या मुझे बस 'u_int32_t' का उपयोग करना चाहिए? –

+1

@LeonGaban एक अनजान राशि, अगर बिल्कुल भी। आपके 32-बिट नंबर को 64-बिट बनने के लिए बढ़ाया जाना है; यदि यह हस्ताक्षरित है, तो यह स्वचालित रूप से 0s के साथ बढ़ाया जाएगा, और यदि यह हस्ताक्षरित और नकारात्मक है, तो यह 1 एस के साथ बढ़ाया जाएगा। यह वास्तव में एक मुद्दा नहीं है। हालांकि, यदि आप 64-बिट संख्या में 32-बिट फ़ंक्शन में पास करने का प्रयास करते हैं, तो आपके नंबर के कुछ हिस्सों को फेंक दिया जा सकता है (फ़ंक्शन केवल 32 बिट्स प्राप्त करता है), और संकलक शिकायत करता है (यही कारण है कि आपको आश्वस्त करें कि आप जानते हैं कि आप एक कलाकार के साथ क्या कर रहे हैं)। –

+0

@LeonGaban दुर्भाग्य से, 'arc4random *' फ़ंक्शंस का कोई 64-बिट संस्करण नहीं है, लेकिन इन्हें कास्ट करना जारी रखें और आप ठीक होंगे। मैं हर जगह 'u_int32_t' का उपयोग करने की सलाह देता हूं क्योंकि यह परिभाषा के अनुसार 32-बिट्स है। ऐप्पल द्वारा लक्षित प्लेटफ़ॉर्म से मिलान करने के लिए 'NSUInteger' को आपके लिए' typedef'd होने का लाभ है, ताकि आप हमेशा इसका उपयोग कर सकें और जान सकें कि आप चीजें कुशलतापूर्वक कर रहे हैं (आप मनमाने ढंग से अपने आकार को सीमित नहीं करना चाहते हैं डेटा जब तक यह समझ में आता है और आवश्यक है)। –

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