সতর্কতা: "বিন্যাসটি স্ট্রিং নয় এবং বিন্যাসের কোনও আর্গুমেন্ট নয়"


110

সর্বশেষতম এক্সকোড ৩.২.১ এবং স্নো লিওপার্ডে আপগ্রেড করার পরে, আমি সতর্কতা পাচ্ছি

"বিন্যাসটি স্ট্রিং আক্ষরিক নয় এবং বিন্যাসের কোনও আর্গুমেন্ট নেই"

নিম্নলিখিত কোড থেকে:

NSError *error = nil;

if (![self.managedObjectContext save:&error]) 
{
    NSLog([NSString stringWithFormat:@"%@ %@, %@", 
       errorMsgFormat, 
       error, 
       [error userInfo]]);      

}

যদি errorMsgFormatএকটি হয় NSStringবিন্যাস নির্দিষ্টকরী সঙ্গে (যেমন: "print me like this: %@"), উপরে সঙ্গে ভুল কি NSLogকল? এবং এটি সংশোধন করার প্রস্তাবিত উপায় কী কী যাতে সতর্কতা উত্পন্ন হয় না?

উত্তর:


113

আপনি কি আপনার বন্ধনীগুলি সঠিকভাবে বাসা বাঁধছেন? আমি মনে করি না যে NSLog()কেবল একটি যুক্তি গ্রহণ করা পছন্দ করে, এটিই আপনি এটি পাস করছেন। এছাড়াও, এটি ইতিমধ্যে আপনার জন্য ফর্ম্যাটিংটি করে। কেন শুধু এই কাজ না?

NSLog(@"%@ %@, %@", 
   errorMsgFormat, 
   error, 
   [error userInfo]);              

বা, যেহেতু আপনি বলছেন errorMsgFormatযে কোনও একক স্থানধারক সহ একটি ফর্ম্যাট স্ট্রিং, আপনি কি এটি করার চেষ্টা করছেন?

NSLog(@"%@, %@", [NSString stringWithFormat:errorMsgFormat, error], 
   [error userInfo]);              

14
"আমি মনে করি না যে এনএসএলগ () কেবল একটি আর্গুমেন্ট NSLog()নেওয়া পছন্দ করে" একটি আর্গুমেন্ট নিতে পারে, যখন ফর্ম্যাট স্ট্রিংয়ের কোনও বিন্যাস নির্দিষ্টকারী থাকে না।
ব্যবহারকারী 102008

ফর্ম্যাট স্ট্রিং দ্বারা ব্যবহৃত না হয়ে অন্য সতর্কতা ডেটা যুক্তি দেয়।
হাসান

157

এক্সকোড অভিযোগ করছে কারণ এটি একটি সুরক্ষা সমস্যা।

আপনার মত কোড এখানে:

NSString *nameFormat = @"%@ %@";
NSString *firstName = @"Jon";
NSString *lastName = @"Hess %@";
NSString *name = [NSString stringWithFormat:nameFormat, firstName, lastName];
NSLog(name);

সর্বশেষ এনএসলগের বিবৃতিটি এর সমতুল্য কার্যকর করতে চলেছে:

NSLog(@"Jon Hess %@");

এটি এনএসএলগকে আরও একটি স্ট্রিং আর্গুমেন্ট সন্ধান করার কারণ হতে চলেছে, তবে একটি নেই। সি ভাষা যেভাবে কাজ করে তার কারণে এটি স্ট্যাক থেকে কিছু এলোমেলো আবর্জনা পয়েন্টার বাছাই করে এটি এনএসএসস্ট্রিংয়ের মতো আচরণ করার চেষ্টা করছে। এটি সম্ভবত আপনার প্রোগ্রামটি ক্রাশ করবে। এখন আপনার স্ট্রিংগুলিতে সম্ভবত% @ এর উপস্থিতি নেই, তবে কোনও দিন তারা সম্ভবত। আপনার সর্বদা ডেটা সহ একটি ফর্ম্যাট স্ট্রিং ব্যবহার করা উচিত যা আপনি ফর্ম্যাট স্ট্রিংগুলি গ্রহণ করে এমন ফাংশনগুলির প্রথম যুক্তি হিসাবে স্পষ্টভাবে নিয়ন্ত্রণ করেন (প্রিন্টফ, স্ক্যানফ, এনএসএলগ, - [এনএসএস স্ট্রিংউথ ফর্ম্যাট:], ...)।

অটো যেমন উল্লেখ করেছে, আপনার সম্ভবত এমন কিছু করা উচিত:

NSLog(errorMsgFormat, error, [error userInfo]);

17
এবং আবারও এসও-তে, বিস্তারিত এবং ভাল উত্তরগুলি পথের দিকে পড়ে। এটি পুরোপুরি ব্যাখ্যা করার জন্য আপনাকে ধন্যবাদ। আমি এটা কখনই বুঝতে পারতাম না
ড্যান রোজনস্টার্ক

38

চূড়ান্ত উত্তর: জোন হেস যেমন বলেছিলেন, এটি একটি সুরক্ষা সমস্যা কারণ আপনি ফর্ম্যাট স্ট্রিংয়ের প্রত্যাশায় কোনও ফাংশনে WHATVER স্ট্রিং পার করছেন। এটি হ'ল এটি যে কোনও স্ট্রিংয়ের সাথে সমস্ত ফর্ম্যাট স্পেসিফায়ারকে মূল্যায়ন করবে। যদি কিছু না থাকে তবে দুর্দান্ত, তবে যদি থাকে তবে খারাপ জিনিস ঘটতে পারে।

তারপরে যথাযথ জিনিসটি হ'ল সরাসরি বিন্যাসের স্ট্রিংটি ব্যবহার করুন

NSLog(@"%@", myNSString);

এইভাবে, মাইএনএসএস্ট্রিংয়ে ফর্ম্যাট নির্দিষ্টকরণকারী থাকলেও তারা এনএসএলগ দ্বারা মূল্যায়ন করে না।


13

আমি বিশেষত এটি ব্যবহার করার পরামর্শ দিচ্ছি না, যেহেতু সতর্কবাণীটি সত্যই সতর্কবাণী .. ভাষার গতিশীল ব্যবহারে স্ট্রিংয়ে রানটাইম করা (যেমন নতুন তথ্য সন্নিবেশ করা বা এমনকি প্রোগ্রামটি ক্র্যাশ করা সম্ভব) করা সম্ভব .. তবে এটি সম্ভব যদি আপনি জানেন যে এটি এমন হওয়া উচিত এবং আপনি সত্যিই এটি সম্পর্কে সতর্ক হতে চান না তবে দমন করার জন্য জোর করা

#pragma GCC diagnostic ignored "-Wformat-security"

সংস্থার সতর্কতাটিকে সাময়িকভাবে উপেক্ষা করার জন্য জিসিসিকে বলবে .. আবার এটি কোনও সমাধান করছে না তবে এমন সময়ও আসতে পারে যখন আপনি সমস্যার সমাধান করার জন্য কোনও ভাল উপায় খুঁজে পেতে পারেন না।

সম্পাদনা: ঝাঁকুনির হিসাবে, প্রাগমা পরিবর্তন হয়েছে। এটি দেখুন: https://stackoverflow.com/a/17322337/3937


10

এটির সমাধানের দ্রুততম উপায় হ'ল @"%@",আপনার NSLogকলটির প্রথম যুক্তি হিসাবে যুক্ত করা , অর্থাত্,

NSLog(@"%@", [NSString stringWithFormat: ....]);

যদিও, আপনার সম্ভবত ষোলটি অটো এর উত্তর বিবেচনা করা উচিত।


10

আমি সবেমাত্র সতর্কবাণীকে অগ্রাহ্য করার শূন্যতা পার করছি, সম্ভবত এটি আপনার পক্ষে কাজ করবে?

এনএসলগ (মাইস্ট্রিং, শূন্য);


5
দ্বিতীয় প্যারামেন্টটি সতর্কতার সমাধান করার সাথে সাথে কেন কেউ শৌখিন হতে পারে তা ব্যাখ্যা করতে পারে?
cprcrack

1
দ্বিতীয় প্যারামিটারের অভাব না থাকলে পাস করার শূন্যতা সুস্পষ্ট। আপনি ধরে নিতে পারেন আপনি বাড়ি থেকে বেরোনোর ​​সময় আপনার অগ্নিকুণ্ড জ্বলানো হয়নি বা আপনি নিশ্চিত করতে পারেন যে এটি ছিল না was সাধারণত আপনার অগ্নিকুণ্ডটি খুব কম ব্যবহার করার কারণে কিছুই ঘটে না, এমন সময় যখন আপনার ঘরটি পুড়ে যায় it

1
@ সোলড আউট অ্যাক্টিভিস্ট অসহায়। এখানে অ-সুস্পষ্ট বক্তব্য (যে কোনও সি ব্যাকগ্রাউন্ড থেকে আসে না এমন ব্যক্তির কাছে) আচরণের মধ্যে পার্থক্য হ'ল সুস্পষ্ট শূন্যস্থান পাস করা এবং কোনও কিছু না পারানো এবং আপনার মন্তব্যটি এটি ব্যাখ্যা করে না।
মার্ক আমেরিকা

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

3
এটি সংকলক সতর্কতা বন্ধ করে দিতে পারে, তবে জোন হেস ব্যাখ্যা করেছেন যে অন্তর্নিহিত সমস্যাটি এখনও বিদ্যমান রয়েছে - যদি একাধিক ফর্ম্যাট নির্দিষ্টকরণকারীর মধ্যে থাকে myStringতবে প্রথমটি ঠিক থাকবে, তবে দ্বিতীয়টি স্তূপ থেকে আবর্জনা তুলবে। @ বিক্রয়, এর বিকল্প তালিকা কখনই নির্ধারিত NSLog()হয় না nil । আর্গুমেন্টের তালিকা কত দীর্ঘ তা নির্ধারণের জন্য দুটি বিকল্প রয়েছে: একটি সেন্ডিনেল মান, বা printf()পরিবারে কী ব্যবহার করা হয় - অন্য যুক্তি যা সংখ্যার গণনা করতে দেয় (উদাহরণস্বরূপ, ফর্ম্যাট স্পেসিফায়ার গণনা করে)।
jscs

3

আপনি যদি একবার এবং সর্বোপরি সতর্কতাটি "স্ট্রিং আক্ষরিক না বিন্যাসের বিন্যাসে" পরিত্রাণ পেতে চান তবে আপনি আপনার টার্গেটের বিল্ড সেটিংসে জিসিসি সতর্কতা সেটিংস "টাইপচেক কল প্রিন্টফ / স্ক্যানফ" (GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO) অক্ষম করতে পারেন।


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

2
সত্য ... এ কারণেই আমি "সমাধান" এর পরিবর্তে "সতর্কতা থেকে মুক্তি পান" পোস্ট করেছি।
aldi

আমি এমন একটি ক্ষেত্রে দৌড়েছি যেখানে উত্স লাইব্রেরিটি এটির utstring_printf ফাংশনের কলগুলিতে এই সতর্কতাটি ট্রিগার করছে, সুতরাং সতর্কতাটি ভুল হওয়ার ক্ষেত্রে এটি দরকারী।
আলফওয়াত

2

এনএসলগ () একটি বিন্যাসের স্ট্রিং প্রত্যাশা করে, যা পাস হচ্ছে তা কেবল একটি স্ট্রিং। আপনার স্ট্রিংউইথ ফরম্যাট ব্যবহার করার দরকার নেই: আপনি কেবল এটি করতে পারেন:

NSLog(@"%@ %@, %@", errorMsgFormat, error, [error userInfo])

এবং এটি সতর্কতাটি দূরে সরিয়ে দেবে।


2

FWIW, এটি আইফোন দেবের জন্যও প্রযোজ্য to আমি ৩.১.৩ এসডিকে বিরুদ্ধে কোডিং করছি এবং একই সমস্যার সাথে একইভাবে ত্রুটি পেয়েছি (এনএসএলগের ভিতরে নেস্টিং স্ট্রিংওয়ে ফর্ম্যাট) ()। সিক্সটেন এবং জনের টাকা আছে।


0

appendFormatNSMutableString ব্যবহার করে কাউকে কেবল জানাতেও যদি এই জাতীয় বিন্যাসিত স্ট্রিংয়ে যাওয়ার চেষ্টা করা হয় তবে এই সতর্কতাটি উপস্থিত হতে পারে:

NSMutableString *csv = [NSMutableString stringWithString:@""];
NSString *csvAddition = [NSString stringWithFormat:@"%@",WHATEVERYOUAREPUTTINGINYOURSTRING];
[csv appendFormat:csvAddition];

সুতরাং এই সতর্কতা এড়ানোর জন্য উপরেরটিকে এটিতে পরিণত করুন:

NSMutableString *csv = [NSMutableString stringWithString:@""];
[csv appendFormat:@"%@",WHATEVERYOUAREPUTTINGINYOURSTRING];

আরও সংক্ষিপ্ত এবং আরও সুরক্ষিত। উপভোগ করুন!


-2
NSLog(@"%@ %@, %@", 
       errorMsgFormat, 
       error, 
       [error userInfo]); 

1
stringWithFormatআপনি যখন এটি করতে পারতেন তা এখানে ব্যবহার অপ্রয়োজনীয়NSLog(@"%@ %@, %@", errorMsgFormat, error, [error userInfo])
মার্ক অ্যামেরি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.