বিন্যাসের আর্গুমেন্ট হিসাবে যখন ব্যবহার করা হয় তখন কেন কোনও এনএসআইঞ্জার ভেরিয়েবলকে দীর্ঘায়িত করতে হয়?


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

উপরের কোডটি একটি ত্রুটি তৈরি করে:

'NSInteger' প্রকারের মানগুলি বিন্যাসের আর্গুমেন্ট হিসাবে ব্যবহার করা উচিত নয়; পরিবর্তে 'দীর্ঘ' এ একটি স্পষ্ট কাস্ট যোগ করুন

সংশোধিত NSLogবার্তাটি আসলে NSLog(@"%lg", (long) myInt);। আমি মানটি প্রদর্শন myIntকরতে longচাইলে আমাকে কেন পূর্ণসংখ্যা মানকে রূপান্তর করতে হবে?


1
@DanielLee, যদি আপনি ব্যবহার NSLog(@"%ld", (long) myInt);, longঢালাই এটি সঙ্গে আপ মেলে করা হয় lএর কোয়ালিফায়ার %ld, কিন্তু যে সব অপ্রয়োজনীয় হিসাবে NSLog(@"%d", myInt);(যথেষ্ট দেওয়া আমরা দেখতে পারি যে যে myIntনয় long। বটম লাইন, আপনি নিক্ষেপ myIntবিন্যাসে দীর্ঘ কোয়ালিফায়ার ব্যবহার করা হয় তবে স্ট্রিং, তবে লম্বা স্ট্রিং ফর্ম্যাট কোয়ালিফায়ার বা longকাস্ট করার দরকার নেই
রব

1
স্পষ্টতই, এটি সত্য নয় যে এনএসএলগ (@ "% i", মাই আইন্ট); যথেষ্ট কারণ আপনি উপরের মতো দেখিয়েছেন ত্রুটি বার্তাটি পাবেন।
ড্যানিয়েল লি

2
@ ড্যানিয়েলি মার্টিন আর এর মন্তব্য দেখুন। আপনি iOS ট্যাগ দিয়ে আপনার প্রশ্ন পোস্ট (যেখানে NSIntegerহয় না দীর্ঘ), কিন্তু শোনাচ্ছে মত আপনি OS X লক্ষ্য (যেখানে সঙ্গে কম্পাইল করছি NSInteger হয় long )।
রব

ওহহ আচ্ছা. আমি জানতাম না যে আইওএস এবং ওএসএক্স এনএসআইন্টারকে বিট এবং টাইপের ক্ষেত্রে আলাদা করবে।
ড্যানিয়েল লি

উত্তর:


193

আপনি ওএস এক্স (-৪-বিট) তে সংকলন করলে আপনি এই সতর্কতাটি পান, কারণ যে প্ল্যাটফর্মটিতে NSIntegerসংজ্ঞায়িত করা হয় longএবং 64৪-বিট পূর্ণসংখ্যা হয়। %iফরম্যাট, অপরপক্ষে, হয় intযা 32 বিট হয়। সুতরাং ফর্ম্যাট এবং আসল পরামিতি আকারে মেলে না।

যেহেতু NSInteger32-বিট বা 64-বিট, প্ল্যাটফর্মের উপর নির্ভর করে, সংকলকটি longসাধারণত একটি কাস্ট যুক্ত করার পরামর্শ দেয় ।

আপডেট: যেহেতু আইওএস 7 এখন 64-বিটকে সমর্থন করে , তাই আইওএসের জন্য সংকলন করার সময় আপনি একই সতর্কতা পেতে পারেন।


1
আইওএস-এ আমি এই ত্রুটিটি পেয়েছি Since. যেহেতু আমি সর্বশেষতম আইফোন 5 এসটি দীর্ঘকাল সেট করে রাখছি তবে এটি 32 বছরের বেশি বিট ডিভাইসে কোনও সমস্যা সৃষ্টি করবে?
প্রীতেশ দেশাই

25
@ বার্টসিম্পসন: "লং" এর কাছে একটি স্পষ্ট কেস সহ NSLog(@"%ld", (long) myInt), এটি 32-বিট এবং 64-বিট সঠিকভাবে কাজ করে।
মার্টিন আর

@ মার্টিনআর যদি আমরা কাস্টিং হয় তবে কেন প্রথম স্থানে দীর্ঘ ব্যবহার করবেন না?
উইলিয়াম এন্টারিকেন

3
@FullDecent: অবশ্যই আপনি দীর্ঘ এখানে কাজ করতে পারেন: long myInt = [myNumber longValue];। তবে অনেকগুলি (মূল) ফাউন্ডেশন পদ্ধতি NS (U) পূর্ণসংখ্যাটিকে প্যারামিটার বা রিটার্ন মান হিসাবে ব্যবহার করে, তাই সাধারণ সমস্যা থেকেই যায়। এছাড়াও আপনার অ্যাপ্লিকেশনটিতে এনএস (ইউ) পূর্ণসংখ্যা ব্যবহার করে -৪-বিট ডিভাইসে আরও বৃহত্তর উপলব্ধ পরিসীমা পেতে এটি বোধগম্য হতে পারে।
মার্টিন আর

39

আপনার ফর্ম্যাট স্পেসিফায়ারগুলি যদি আপনার ডেটার ধরণের সাথে মেলে তবে আপনাকে কোনও কিছুতে কাস্ট করতে হবে না। NSIntegerদেশীয় ধরণের ক্ষেত্রে কীভাবে সংজ্ঞায়িত করা হয় তার বিশদ জন্য মার্টিন আর এর উত্তর দেখুন ।

সুতরাং কোডটি 64-বিট পরিবেশের জন্য তৈরি করার উদ্দেশ্যে, আপনি আপনার লগ স্টেটমেন্টগুলি এভাবে লিখতে পারেন:

NSLog(@"%ld",  myInt); 

32-বিট পরিবেশের জন্য আপনি লিখতে পারেন:

NSLog(@"%d",  myInt); 

এবং এটি কাস্ট ব্যতীত সমস্ত কাজ করবে।

যাইহোক ক্যাস্টগুলি ব্যবহার করার একটি কারণ হ'ল ভাল কোডটি প্ল্যাটফর্মগুলির জুড়ে পোর্ট করা থাকে এবং আপনি যদি নিজের ভেরিয়েবলগুলি স্পষ্টভাবে কাস্ট করেন তবে এটি 32 এবং 64 বিট উভয়ের জন্য পরিষ্কারভাবে সংকলন করবে:

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

এবং লক্ষ্য করুন যে এটি কেবল এনএসএলগের বিবৃতিগুলির জন্যই নয়, যা কেবলমাত্র পরে ডিবাগিং এইডগুলি করছে, তবে এর জন্য [NSString stringWithFormat:]এবং বিভিন্ন উত্পন্ন বার্তাগুলি, যা উত্পাদন কোডের বৈধ উপাদান।


1
সুতরাং এখন যেহেতু এই হ্যাকটি প্রয়োজনীয়, এটি এখনও প্রথম স্থানে এনএসইন্টেজার ব্যবহার করা ভাল অনুশীলন?
উইলিয়াম এন্টারিকেন

@ ফুলডিসেন্ট এটি কোডটিতে কেবলমাত্র সমস্যা যা রানটাইম ব্যাখ্যা করা হয় যেমন ফর্ম্যাট স্ট্রিং। একটি সংকলিত কোড এনএসআইন্টার টাইপডেফের সুবিধা গ্রহণ করে।
মনোলো

এটি এনএসআইন্টিজার ব্যবহার করা সবচেয়ে ভাল অনুশীলন, কারণ এটি সংজ্ঞায়িত করার কারণেই এটি সংজ্ঞায়িত করার জন্য ভাল কারণ রয়েছে।
gnasher729

22

NSLog এ NSInteger পাস করার পরিবর্তে, কেবল একটি NSNumber পাস করুন। এটি সমস্ত ক্যাসেটের আশেপাশে এবং সঠিক স্ট্রিং ফর্ম্যাট স্পেসিফায়ার বেছে নেবে।

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

এটি NSUIntegers এর জন্য চিন্তা না করেও কাজ করে। NSInteger এবং NSUInteger এর উত্তর মিশ্রিত 64 বিট / 32 বিট পরিবেশে দেখুন


2
আমি মনে করি নির্বাচিত উত্তরটি প্রযুক্তিগতভাবে প্রশ্নের উত্তরের উত্তর, তবে আপনি যদি প্রতিটি ঘটনা কাস্টিং এড়াতে এবং সতর্কতাগুলি রোধ করতে চান তবে আমি খুঁজে পেতে পারি এটিই সেরা সমাধান।
ড্যানিয়েল উড

0

এটি ব্যবহার করার সময় সতর্কতা রাখে NSLog(@"%ld", (long)myInt);, তবে long myInt = 1804809223;আইওএস 10-এ পরিবর্তন ঘোষণার পরে সতর্কতা বন্ধ করে ।


-2

ওএস এক্স 32- এবং 64-বিট পরিবেশে মানগুলি উপস্থাপনের ধারাবাহিক মাধ্যম সরবরাহ করতে বেশ কয়েকটি ডেটা ধরণের — NSInteger, NSUInteger, CGFloat এবং CFIndex uses ব্যবহার করে। একটি 32-বিট পরিবেশে, NSInteger এবং NSUInteger যথাক্রমে int এবং স্বাক্ষরবিহীন int হিসাবে সংজ্ঞায়িত করা হয়। 64-বিট পরিবেশে, NSInteger এবং NSUInteger যথাক্রমে দীর্ঘ এবং স্বাক্ষরবিহীন দীর্ঘ হিসাবে সংজ্ঞায়িত করা হয়েছে। প্ল্যাটফর্মের উপর নির্ভর করে বিভিন্ন প্রিন্টফ-স্টাইলের ধরণের স্পেসিফায়ার ব্যবহারের প্রয়োজনীয়তা এড়াতে, আপনি 32 বিট এবং 64 বিট উভয় পরিবেশের জন্য এই লিঙ্কটিতে প্রদর্শিত স্পেসিফায়ার ব্যবহার করতে পারেন ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.