কীভাবে 'অঘোষিত নির্বাচক' সতর্কতা থেকে মুক্তি পাবেন


162

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

if ([self respondsToSelector:@selector(setError:)])
{
    [self performSelector:@selector(setError:) withObject:[NSError errorWithDomain:@"SomeDomain" code:1 userInfo:nil]];
}

যাইহোক, সংকলকটি সেট-এররার: স্বাক্ষর সহ কোনও পদ্ধতি দেখতে পাচ্ছে না, সুতরাং এটি আমাকে একটি সতর্কতা দেয়, যেখানে প্রতিটি @selector(setError:)স্নিপেট থাকে:

Undeclared selector 'setError:'

এই সতর্কতা থেকে মুক্তি পেতে আমার কোনও প্রোটোকল ঘোষণা করতে হবে না, কারণ আমি এমন সমস্ত শ্রেণি চাই না যা বিশেষ কিছু প্রয়োগ করতে এটি ব্যবহার করতে পারে। কেবল কনভেনশন করে আমি তাদের একটি setError:পদ্ধতি বা সম্পত্তি থাকতে চাই।

এটা কি করণীয়? কিভাবে?

চিয়ার্স,
ইপি



একজন অবহেলিত নির্বাচক সতর্কবার্তা তৈরি করবে। নির্বাচককে আর অ্যাক্সেস করা নিরাপদ নয় কারণ কিছু সময় নির্বাচককে অপসারণ করা যেতে পারে।
ডনসং

উত্তর:


254

আরেকটি বিকল্প হ'ল সতর্কতাটি এর সাথে অক্ষম করা:

#pragma GCC diagnostic ignored "-Wundeclared-selector"

সতর্কতাটি ঘটে সেখানে আপনি এই লাইনটি এম। এম ফাইলে রাখতে পারেন।

হালনাগাদ:

এটি LLVM এর সাথেও এইভাবে কাজ করে:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"

... your code here ...

#pragma clang diagnostic pop

#pragma clang diagnostic push #pragma clang diagnostic ignored "-Wundeclared-selector" // Do your thing #pragma clang diagnostic pop
চকচকে

হ্যাঁ, এটি @ ডিজি যেমন বলেছে তেমন করে। (দেরিতে উত্তরের জন্য দুঃখিত, তবে আমি বিজ্ঞপ্তিটি মিস করেছি)।
ক্লাস

আমার আলসনের প্রয়োজন#pragma clang diagnostic ignored "-Wselector"
সর্বাধিক

1
@mdorseif বেশিরভাগ সময় সতর্কতা যে আপনাকে 'বাদ দিতে হবে' তা কম্পাইল লগে তালিকাভুক্ত করা হয়েছে। আপনি এই ধারণাটি সহ যে কোনও সতর্কতা নিঃশব্দ করতে পারেন। আপনি নির্বাচকদের সম্পর্কে আপনার যোগ করেছেন খুশি।
ক্লাস

@ অ্যাপলজি আপনি বিল্ড সেটিং "অঘোষিত নির্বাচনকারী"

194

এনএসএসইলেক্টর ফ্রেমস্ট্রিং এ দেখুন ।

 SEL selector = NSSelectorFromString(@"setError:");
 if ([self respondsToSelector:selector])

এটি আপনাকে @selectorকীওয়ার্ডের মাধ্যমে সঙ্কলনের পরিবর্তে রানটাইমের সময় একটি নির্বাচক তৈরি করতে দেয় এবং সংকলকটির কাছে অভিযোগ করার কোনও সুযোগ থাকবে না।


হাই @ সার্জিও, আপনার এবং @ জোকোব্রেলকিনের উত্তর উভয়ই কাজ করে। বেশ এক সাথে জমা দেওয়া। আপনি যদি আমাকে 'আরও ভাল' উত্তরটি বেছে নিতে সহায়তা করেন, যদি একটি উত্তর থাকে?
এপোলোজি

2
আমি এই উত্তরটি বেশি পছন্দ করি কারণ এটি আরও "কোকো" -y (?) দেখায়। sel_registerName()অজানা সৌন্দর্য অস্পষ্ট এবং ধরনের আপনি সরাসরি কল করতে হবে যদি না আপনি জানেন আপনি কি করছেন, obj_msg_send () মত ধরণ;)
নিকোলাস Miari

15
এটি এক্সকোড 5 কিনা তা নিশ্চিত নয় তবে আমি এই প্রয়োগের সাথে একটি পৃথক সতর্কতা পাচ্ছি : "পারফর্মস্লেেক্টর একটি ফাঁস হতে পারে কারণ এর নির্বাচকটি অজানা"
হ্যাম্পডেন 123

1
@ হ্যাম্পডেন 123: এটি একটি ভিন্ন বিষয়। এখানে একবার দেখুন: স্ট্যাকওভারফ্লো.com
প্রশ্নগুলি

52

আমি মনে করি এটি কারণ কারণটি কিছু অদ্ভুত কারণে নির্বাচক রানটাইমের সাথে নিবন্ধিত হয়নি।

এর মাধ্যমে নির্বাচককে নিবন্ধিত করার চেষ্টা করুন sel_registerName():

SEL setErrorSelector = sel_registerName("setError:");

if([self respondsToSelector:setErrorSelector]) {
   [self performSelector:setErrorSelector withObject:[NSError errorWithDomain:@"SomeDomain" code:1 userInfo:nil]];
}

হাই @ জ্যাকোব্রেলকিন, আপনার এবং @ সার্জিওর উত্তর উভয়ই কাজ করে। বেশ এক সাথে জমা দেওয়া। আপনি যদি আমাকে 'আরও ভাল' উত্তরটি বেছে নিতে সহায়তা করেন, যদি একটি উত্তর থাকে?
এপোলোজি

2
@ অ্যাপোলোজি যাইহোক হুডের নীচে NSSelectorFromStringকল করে sel_registerName()। যেটি আপনার পক্ষে সবচেয়ে বেশি উপযুক্ত তা চয়ন করুন।
জ্যাকব রিলকিন

1
@ অ্যাপোলজি আমি মনে করি sel_registerName()আপনি কেন করছেন তা সম্পর্কে সরাসরি কল করা আরও স্পষ্ট। NSSelectorFromStringনা বলতে আপনি যে এটা নির্বাচক নিবন্ধন চেষ্টা যাচ্ছে।
জ্যাকব রিলকিন

8
এটি এক্সকোড 5 কিনা তা নিশ্চিত নয় তবে আমি এই প্রয়োগের সাথে একটি পৃথক সতর্কতা পাচ্ছি : "পারফর্মস্লেেক্টর একটি ফাঁস হতে পারে কারণ এর নির্বাচকটি অজানা"
হ্যাম্পডেন 123

নিচে আমার অন্যান্য মন্তব্য দেখুন। আমি এটিতে খুব বেশি সময় ব্যয় করতে চাইনি তাই আমি কেবল হেডার ফাইলগুলি অন্তর্ভুক্ত করেছি।
হ্যাম্পডেন 123

7

পদ্ধতিটির সাথে ফাইলটি # অন্তর্ভুক্ত করে আমি বার্তাটি পেয়েছি। এই ফাইলটি থেকে আর কিছুই ব্যবহার করা হয়নি।


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

2
শীর্ষ ভোটের দুটি উত্তরই সঠিক নয়। "অঘোষিত নির্বাচক" সতর্কতার উদ্দেশ্যটি হ'ল সংকলনকালে ত্রুটিগুলি ধরা যদি আপনি নির্ভরশীল নির্বাচকটির নাম পরিবর্তন করেন। সুতরাং আপনি যে ফাইলটির উপর নির্ভরশীল ছিলেন তা ঘোষণা করে এমন ফাইলটিকে ইমপোর্ট করা সবচেয়ে সঠিক।
ব্রেন

7

আমি বুঝতে পারি যে আমি এই থ্রেডে কিছুটা দেরি করেছি তবে সম্পূর্ণতার জন্য, আপনি বিশ্বব্যাপী লক্ষ্য নির্ধারণ সেটিংস ব্যবহার করে এই সতর্কতাটি বন্ধ করতে পারেন।

বিভাগে, 'অ্যাপল এলএলভিএম সতর্কতা - উদ্দেশ্য-সি', পরিবর্তন করুন:

Undeclared Selector - NO

6

যদি আপনার শ্রেণি সেটারার: ​​পদ্ধতিটি কার্যকর করে (এমনকি চূড়ান্ত ত্রুটি সম্পত্তিটির গতিশীল সেটটার ঘোষণা করে) আপনি এটি আপনার ইন্টারফেস ফাইলে (। এইচ) প্রকাশ করতে চাইতে পারেন, বা যদি আপনি এটি সেভাবে দেখাতে না চান তবে প্রাইভেট ম্যাথডসের কৌতুকপূর্ণ কৌশলটি ব্যবহার করে দেখুন:

@interface Yourclass (PrivateMethods)

- (void) yourMethod1;
- (void) yourMethod2;

@end

আপনার @ কার্যকরকরণের ঠিক আগে, এটি সতর্কতাগুলি আড়াল করা উচিত;)।


ধন্যবাদ, তবে আমি একটি বিভাগ থেকে পদ্ধতিটি কল করছি, সুতরাং এটি প্রযোজ্য নয়। চিয়ার্স, ইপি।
এপোলোজি

এবং আমাদের মধ্যে কিছু এমন জিনিস করছেন যা আরও বহিরাগত - নির্বাচক আমার ক্ষেত্রে এফ # অবজেক্টে প্রয়োগ করা হয়েছে।
জেমস মুর

1
এটি PerformSelector may cause a leak because its selector is unknown
এক্সকোড

3

সত্যিই একটি আরামদায়ক ম্যাক্রো আপনার করা .pchবা Common.hবা যেখানেই আপনি চান:

#define SUPPRESS_UNDECLARED_SELECTOR_LEAK_WARNING(code)                        \
_Pragma("clang diagnostic push")                                        \
_Pragma("clang diagnostic ignored \"-Wundeclared-selector"\"")     \
code;                                                                   \
_Pragma("clang diagnostic pop")                                         \

অনুরূপ সমস্যার জন্য এটি এই প্রশ্নের একটি সম্পাদনা ...


3

আপনি এটি স্ক্রিনশটের মতো এক্সকোডে বন্ধ করতে পারেন:

এখানে চিত্র বর্ণনা লিখুন


সুন্দর. তবুও, আমি কেবল স্পষ্ট মামলার জন্য সতর্কতাটি অক্ষম করা পছন্দ করি, "এই উপলক্ষে ঝনঝনানি ভুল, আমি জানি আমি কী করছি" বলার মাধ্যমে। আপনার ইনপুট জন্য ধন্যবাদ!
এপোলোজি

2

সতর্কতা এড়াতে আপনি প্রথমে কোনও আইডিতে প্রশ্নের মধ্যে প্রশ্নটি ফেলে দিতে পারেন:

if ([object respondsToSelector:@selector(myMethod)]) {
    [(id)object myMethod];
}

1
এটি যদি আজ পর্যন্ত এক্সসি 7.1 অবধি অভিব্যক্তি সামগ্রীগুলিতে একই সতর্কতা থেকে মুক্তি পায় না।
মার্টিন-গিলস লাভোই

2

এই সতর্কতাটি এড়ানোর আরেকটি উপায় হ'ল আপনার নির্বাচক পদ্ধতিটি দেখে মনে হচ্ছে তা নিশ্চিত করা:

-(void) myMethod :(id) sender{
}

আপনি যদি কোনও প্রেরককে গ্রহণ করতে চান বা "প্রেরক অবজেক্টের ধরণ নির্দিষ্ট করতে চান তবে" (আইডি) প্রেরককে ভুলে যাবেন না।


0

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


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

1
আমাকে মনে করিয়ে দেওয়ার জন্য ধন্যবাদ যে আমার সম্ভবত কোনও মন্তব্য করা উচিত ছিল। আমি কেবল এটিই বলতে পারি যে অনুপস্থিত আমদানিগুলির কারণে এই নির্দিষ্ট উদাহরণটি না থাকলে এই এক্সকোড সতর্কতাও ঘটায়। রানটাইমের সময় নির্বাচক তৈরি করার সময় বা গতিশীল ফ্যাশনে পদ্ধতি কলগুলিতে প্রতিক্রিয়া জানানোর সময় আমি কেবল এনএসইলেক্টরফ্রস্ট্রস্ট্রিং বা এই জাতীয় "রেজিস্ট্রেশন" বিকল্পগুলির প্রস্তাব করব (উদাহরণস্বরূপ, মেইনসাইনচারেফোরসলেটর)। এটি নিবন্ধভুক্ত করার অর্থ আপনি "ত্রুটিটি নিয়ে কাজ করছেন" এবং তাই কিছু পরিস্থিতিতে এটি সঠিক নয়, কারণ আরও সঠিক পদ্ধতির হ'ল সতর্কতাটি সংশোধন করা হবে (যদি ঝনঝন বিশ্লেষণটি সঠিক ছিল, এটি ছিল))
লুই সেন্ট-আমুর

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

-1

আমি তত্পরতা পদ্ধতি যোগ করে সতর্কতাটি পেতে সক্ষম হয়েছি (প্রকাশ: আমি এটি ভেবে দেখিনি তবে এটি শিডিউলডাইমারটাইমিনটারওয়ালগুলিতে গুগল করে পেয়েছি)

    [NSTimer scheduledTimerWithTimeInterval:[[NSDate distantFuture] timeIntervalSinceNow]
                                     target:self
                                   selector:@selector(donothingatall:)
                                   userInfo:nil
                                    repeats:YES];


    [[NSRunLoop currentRunLoop] run];

    HTTPLogVerbose(@"%@: BonjourThread: Aborted", THIS_FILE);

    }
}

+ (void) donothingatall:(NSTimer *)timer
{

}

সতর্কবার্তাটি কীভাবে আড়াল করতে হবে তা জানার জন্য আমি প্রশংসা করি, তবে এটি ঠিক করা ভাল এবং অজানা কারণে সার্জিও বা রিলকিনের কৌশলগুলিও আমার পক্ষে কার্যকর হয়নি।


1
যদি অন্য কেউ এই সমাধানটি পড়েন যা কার্যকর হবে , তবে সে আপনার ভবিষ্যতের স্বতন্ত্র সহ বেশ বিভ্রান্ত হবে। যদি আপনি নিশ্চিত হন যে আপনি কোনও অ-বিদ্যমান নির্বাচককে কল করে কী করছেন, যার ফলে একটি সতর্কতা দেখা দিয়েছে, বিভ্রান্তিকর পদ্ধতি স্টাবটি এড়িয়ে যান এবং নিশ্চিত করুন যে আপনার কোডটি আপনার অভিপ্রায় প্রকাশ করেছে resses
এপোলোজি

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