অবজেক্টিভ-সি-তে একটি @ প্রোটোকলের কাছে একটি শ্রেণীর উদাহরণ দিন


102

আমার কাছে একটি অবজেক্ট (একটি ইউআইভিউকন্ট্রোলার) রয়েছে যা আমি সংজ্ঞায়িত প্রোটোকলের সাথে সামঞ্জস্য হতে পারি বা নাও করতে পারি।

আমি জানি যে আমি নির্ধারণ করতে পারি যে বিষয়টি যদি প্রোটোকলের সাথে সম্মতি দেয় তবে নিরাপদে পদ্ধতিটি কল করুন:

if([self.myViewController conformsToProtocol:@protocol(MyProtocol)]) {
    [self.myViewController protocolMethod]; // <-- warning here
}

তবে এক্সকোড একটি সতর্কতা দেখায়:

warning 'UIViewController' may not respond to '-protocolMethod'

এই সতর্কতাটি রোধ করার সঠিক উপায় কী? আমি ক্লাস self.myViewControllerহিসাবে কাস্ট করতে পারে না MyProtocol

উত্তর:


171

এটি করার সঠিক উপায়টি হ'ল:

if ([self.myViewController conformsToProtocol:@protocol(MyProtocol)])
{
        UIViewController <MyProtocol> *vc = (UIViewController <MyProtocol> *) self.myViewController;
        [vc protocolMethod];
}

UIViewController <MyProtocol> *টাইপ ঢালাই অনুবাদ ব্যবহার যেহেতু "ভিসি একটি UIViewController বস্তুর MyProtocol কে কনর্ফাম করে যে" id <MyProtocol>অনুবাদ "ভিসি একটি অজানা বর্গ যে MyProtocol কে কনর্ফাম করে একটি অবজেক্ট হয়"।

এইভাবে সংকলক আপনাকে যথাযথ প্রকারের পরীক্ষা করতে হবে vc- সংকলক কেবল তখনই একটি সতর্কতা দেবে যদি কোনও পদ্ধতিই ঘোষণা করা হয় না UIViewControllerবা <MyProtocol>ডাকা হয় না । idযদি আপনি অবজেক্টের /ালাইয়ের শ্রেণি / প্রকারটি জানেন না তবেই পরিস্থিতিতে ব্যবহার করা উচিত।


2
প্রোটোকল ব্যবহার করার সময় আপনার অবজেক্টের ধরণের বিষয়ে সত্যই যত্ন নেওয়া উচিত নয় - কোনও প্রোটোকলের পুরো বিষয়টি হ'ল যে কোনও বস্তুর ধরণ এটি অবলম্বন করতে পারে এবং নির্দিষ্ট অবজেক্টে কাস্ট না করে ব্যবহার করতে পারে। সুতরাং, আমি উপরে id<MyProtocol> p = (id<MyProtocol>)self.myViewController;উত্তরগুলির পরিবর্তে আপনি যে কোনও জায়গায় প্রোটোকলে কাস্ট করছেন সেই উত্তরটি @ এবং এর দ্বারা ব্যবহার করার পরামর্শ দেব - এই উত্তর এবং @ এন্ডিস উভয়ই সঠিক, তবে তার আরও সঠিক।
স্মরণে

2
@ উত্তরবোট আপনার মন্তব্যটি ভুল এবং আমার উত্তরের শেষ অনুচ্ছেদে আমি যে বক্তব্যটি দিয়েছি তা মিস করে। আপনি হয়ত বা অবজেক্টের ধরণের যত্ন নিতে পারেন না, এটি পরিস্থিতির উপর নির্ভর করে। আপনি একটি বার্তা ঘোষিত পাঠাতে চান তাহলে কি হবে UIViewControllerথেকে vcআমার উত্তর উদাহরণে, এবং এটি হিসাবে ঘোষণা করে id <MyProtocol>?
নিক ফরজ

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

আপনি এটি দেখেন নি / ব্যবহার করেন নি কেবল এর অর্থ এটি কোনও কোড গন্ধ। এখানে একটি কোড স্নিপেট রয়েছে যেখানে উদাহরণস্বরূপ তথ্য ব্যবহার করে ফেলে দেওয়া idসমস্যা রয়েছে তার উদাহরণ রয়েছে : gist.github.com/nsforge/7743616
নিক

60

আপনি এটি এর মতো নিক্ষেপ করতে পারেন:

if([self.myViewController conformsToProtocol:@protocol(MyProtocol)])
{
    id<MyProtocol> p = (id<MyProtocol>)self.myViewController;
    [p protocolMethod];
}

এটি আমাকেও কিছুটা ফেলে দিয়েছে। অবজেক্টিভ-সি-তে, প্রোটোকলটি নিজেই টাইপ হয় না, তাই আপনার প্রোটোকলের পাশাপাশি আপনাকে id(বা অন্য কোনও ধরণের যেমন NSObject) নির্দিষ্টকরণ প্রয়োজন ।


আহ, শান্ত, ধন্যবাদ আমি কেবল যাচাই করে দেখেছি যে এটি (id)কাজ হিসাবে কাজ করাও কাজ করে। এটা কি খারাপ ফর্ম?
ফোর্ড

1
যদি আপনি এটিকে << MyProtocol> হিসাবে কাস্ট করেন তবে আপনি যদি সেই প্রোটোকলটিতে সংজ্ঞায়িত নয় এমন পদ্ধতি ব্যবহার করেন তবে সংকলক আপনাকে সতর্ক করবে।
ড্রিমলাক্স

1
@ ড্রিমলাক্স - সংকলক প্রোটোকলের বিপরীতে পরীক্ষা টাইপ করে। আরও তথ্যের জন্য বিকাশকারী.অ্যাপল . com/ ডকুমেন্টেশন / কোকো / কনসেপ্টুয়াল / অবজেক্টিভ সি/… দেখুন ।
অ্যান্ডি

1
@ ফোর্ড - বিশেষত প্রোটোকলটি ব্যবহার করা আরও ভাল হবে, যেহেতু সংকলকটি আপনার জন্য কিছু প্রকারের পরীক্ষা করতে পারে।
অ্যান্ডি

1
@ অ্যান্ডি, আমি মনে করি না যে আপনার '*' দরকার যেহেতু 'আইডি' ইতিমধ্যে পয়েন্টার হিসাবে রয়েছে। সুতরাং: আইডি <মাইপ্রোটোকল> পি = (আইডি <মাইপ্রোটোকল>) স্ব.মাইভিউকন্ট্রোলার; [পি প্রোটোকল ম্যাথোদ]; বা কেবল: [(আইডি <মাইপ্রোটোকল>) স্ব.মাইভিউকন্ট্রোলার প্রোটোকল ম্যাথড];
ফোর্ড
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.