অবজেক্টিভ-সি অন্তর্নিহিত রূপান্তরটি 'এনএসইউইন্টেজার' (ওরফে 'স্বাক্ষরবিহীন লম্বা') 'ইনট' সতর্কতার জন্য হারান


187

আমি কিছু অনুশীলনের মধ্য দিয়ে কাজ করছি এবং একটি সতর্কতা পেয়েছি যা জানিয়েছে:

অন্তর্নিহিত রূপান্তর পূর্ণসংখ্যার নির্ভুলতা হারিয়ে ফেলে: 'এনএসইউইন্টেজার' (ওরফে 'স্বাক্ষরবিহীন দীর্ঘ') থেকে 'ইনট'

#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পদ্ধতি NSArrayআয় একটি NSUInteger, এবং 64-বিট OS X এর প্ল্যাটফর্মের উপর

  • NSUIntegerহিসাবে সংজ্ঞায়িত করা হয় unsigned long, এবং
  • unsigned long একটি 64-বিট স্বাক্ষরবিহীন পূর্ণসংখ্যার পূর্ণসংখ্যা।
  • int এটি একটি 32-বিট পূর্ণসংখ্যা।

সুতরাং intচেয়ে একটি "ছোট" ডাটাটাইপ হয় NSUInteger, অতএব কম্পাইলার সতর্কবার্তা।

"ফাউন্ডেশন ডেটা টাইপস রেফারেন্স" এ NSUInteger দেখুন :

32-বিট অ্যাপ্লিকেশনগুলি তৈরি করার সময়, এনএসইউইন্টেজারটি 32-বিট স্বাক্ষরবিহীন পূর্ণসংখ্যা। একটি 64-বিট অ্যাপ্লিকেশন NSUInteger কে একটি 64-বিট স্বাক্ষরবিহীন পূর্ণসংখ্যার হিসাবে বিবেচনা করে।

এই সংকলক সতর্কতা ঠিক করতে, আপনি হয় স্থানীয় countভেরিয়েবল হিসাবে হিসাবে ঘোষণা করতে পারেন

NSUInteger count;

অথবা (আপনি যদি নিশ্চিত হন যে আপনার অ্যারেতে 2^31-1উপাদানগুলির চেয়ে বেশি কখনই থাকবে না !), একটি স্পষ্ট কাস্ট যোগ করুন:

int count = (int)[myColors count];

19
কেবল যোগ করার জন্য - আমি আমার এক্সকোড 5 প্রকল্পে হঠাৎ সতর্কতা এবং ত্রুটিযুক্ত ক্র্যাপ লোড পেয়েছি বলে আমি এই উত্তরটি দিয়েছি। আপনি 64 বিট উল্লেখ করেছেন যা আমাকে আমার বিল্ড সেটিংস দেখতে সহায়তা করে। এক্সকোড এটিকে 64 বিট মোডে পরিবর্তন করেছে যা ত্রুটিগুলি ছুঁড়ে দিয়েছে। এটিকে আরভিএম 7 এ পরিবর্তন করা তাদের সকলকে ঠিক করে দিয়েছে।
রবার্ট জে ক্লিগ

1
@ টেন্ডার কি ভার্চ vs৪ বিট কম্পাইল করার মধ্যে পারফরম্যান্সের পার্থক্য রয়েছে?
শন বুধরাম

1
@ শৈন বুধরাম এর চেহারা দেখে কিছুই হ'ল না। আমি কোন পার্থক্য দেখিনি। এটি কেবলমাত্র অ্যাপ্লিকেশনগুলিতেই একটি পার্থক্য তৈরি করবে যেগুলি সিপিইউকে ভারী ব্যবহার করে - উদাহরণস্বরূপ গেমসগুলি benefit৪ বিটের জন্য একটি সুবিধার সংকলন দেখতে পাবে।
রবার্ট জে ক্লেগ

7
"১ ফেব্রুয়ারি, ২০১৫ থেকে, অ্যাপ স্টোরটিতে আপলোড করা নতুন আইওএস অ্যাপ্লিকেশনগুলিতে অবশ্যই -৪-বিট সমর্থন অন্তর্ভুক্ত থাকতে হবে ..." - অ্যাপল বিকাশকারী সংবাদ এবং আপডেটগুলি, অক্টোবর ২০, ২০১৪
পাং

2
@ জয়প্রকাশডুবি: অ্যাপ্লিকেশন আপনার সংকলক সতর্কতা দেখতে পাচ্ছে না কারণ আপনি বাইনারি সংকলিত অ্যাপ্লিকেশন অ্যাপ স্টোরটিতে জমা দিয়েছেন Apple তাই সংকলক সতর্কতার কারণে আপনার অ্যাপ্লিকেশনটিকে প্রত্যাখ্যান করা যাবে না। আপনার অ্যাপ্লিকেশনটি সঠিকভাবে কাজ করতে আপনার এগুলি ঠিক করা উচিত।
মার্টিন আর

24

মার্টিনের উত্তরের বিপরীতে, কন্ট্রাস্ট করা (বা সতর্কতা উপেক্ষা করে) castালাই সর্বদা নিরাপদ নয় এমনকি আপনি যদি জানেন যে আপনার অ্যারেতে 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

@ moonman239 সাধারণভাবে, কাস্টিং (তার দ্বিতীয়) এর বিপরীতে আমি সম্ভব হলে সঠিক টাইপের একটি পরিবর্তনশীল (@ মার্টিনআর এর প্রথম পরামর্শ) ব্যবহার করব। যেমনটি তিনি উল্লেখ করেছেন, particularালাই এই বিশেষ ক্ষেত্রে নিরাপদ, তবে আমি মনে করি এটি প্রবেশ করা একটি দরিদ্র অভ্যাস, কারণ এটির অপ্রত্যাশিত পরিণতি হতে পারে (আমার উদাহরণ হিসাবে)। আমি পোস্ট করেছি কারণ আমাকে এই নির্দিষ্ট পরিস্থিতির দ্বারা দংশিত করা হয়েছে (যদিও এটি == সংকলক সতর্কবার্তা সম্পর্কে একটি ভাল বিষয়, যা আমি অবশ্যই মিস করেছি)।
অ্যাড্রিয়ান

2
আমার মনে হয় ইন্ডেক্সঅফবজেক্টের চেয়ে গণনা অনেক বেশি ব্যবহৃত হবে এবং এনএসআইন্টেজারের সাথে একটি "লুপ" কোডিং স্টাইল না রাখার জন্য লুপটি ফোটানো বাজে কথা। আপনার কেবলমাত্র সূচিপত্রের জন্য দেখতে হবে এবং সেখানে এনএসআইন্টিজার ব্যবহারের বিষয়টি নিশ্চিত করা উচিত, যে কোনও কিছুকে কেবল কিছু হিসাবে গণনা করা হয় তা বিশেষভাবে একটি পদ্ধতির ফোকাসের মধ্যে
নিকিডি

5

প্রজেক্টে কী পরিবর্তন করুন> বিল্ড সেটিং " প্রিন্টফ / স্ক্যানফে টাইপচেক কলগুলি : না "

ব্যাখ্যা: [এটি কীভাবে কাজ করে]

প্রিন্টফ এবং স্ক্যানফ ইত্যাদিতে কলগুলি পরীক্ষা করুন, সরবরাহ করা আর্গুমেন্টগুলিতে নির্দিষ্ট করা ফর্ম্যাট স্ট্রিংয়ের উপযুক্ত প্রকার রয়েছে এবং তা ফর্ম্যাট স্ট্রিংয়ে বর্ণিত রূপান্তরগুলি অর্থবোধ করে তা নিশ্চিত করার জন্য।

আশা করি এটি কার্যকর হবে

অন্য সতর্কতা

উদ্দেশ্য সি অন্তর্ভুক্ত রূপান্তর পূর্ণসংখ্যা নির্ভুলতা 'এনএসইউইন্টেজার' (ওরফে 'স্বাক্ষরবিহীন দীর্ঘ') থেকে 'ইনট'

কী " 32 বিট প্রকারের> সংযুক্ত রূপান্তর> ডিবাগ> * 64 আর্কিটেকচার: নেই " পরিবর্তন করুন

[ সতর্কতা: এটি B৪ বিট আর্কিটেকচার রূপান্তর সম্পর্কিত অন্যান্য সতর্কতা বাতিল করতে পারে]


যদি আপনি কেবলমাত্র 32 টি বিট লাইব্রেরিকে 64 বিটে রূপান্তর করতে চান তবে এটি একটি আশাব্যঞ্জক বিকল্প।
সান

2

"ইনট" তে এক্সপিসিট কাস্টিং করা আমার ক্ষেত্রে সমস্যাটি সমাধান করে। আমারো একই ইস্যু ছিল. তাই:

int count = (int)[myColors count];

বা একে "অন্তর্নিহিত" বলা হয়? LOL :) উভয় ক্ষেত্রেই, এটি কাজ করেছিল।
ভ্লাদিমির দেশপোটোভিচ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.