আমি কীভাবে 'খাঁটি' সুইফটে (@objc ছাড়াই) দুর্বল প্রোটোকল রেফারেন্স করতে পারি


561

weakরেফারেন্সগুলি সুইফটিতে কাজ করার মতো মনে হয় না যতক্ষণ না একটি protocolহিসাবে ঘোষিত হয় @objc, যা আমি খাঁটি সুইফট অ্যাপ্লিকেশনটিতে চাই না।

এই কোডটি একটি সংকলন ত্রুটি দেয় ( weakঅ-শ্রেণীর ধরণের ক্ষেত্রে প্রয়োগ করা যায় না MyClassDelegate):

class MyClass {
  weak var delegate: MyClassDelegate?
}

protocol MyClassDelegate {
}

আমার প্রোটোকলটি প্রিফিক্স করা উচিত @objc, তারপরে এটি কার্যকর হয়।

প্রশ্ন: একটি সম্পূর্ণ করার জন্য 'খাঁটি' সুইফট উপায় কী weak delegate?


উত্তর:


1038

আপনাকে প্রোটোকলের ধরণের হিসাবে ঘোষণা করতে হবে AnyObject

protocol ProtocolNameDelegate: AnyObject {
    // Protocol stuff goes here
}

class SomeClass {
    weak var delegate: ProtocolNameDelegate?
}

AnyObjectআপনি ব্যবহার করে বলছেন যে কেবল ক্লাসগুলিই এই প্রোটোকলের সাথে সামঞ্জস্য করতে পারে, যেখানে স্ট্রাক্ট বা এনামগুলি পারে না।


25
এই সমাধানগুলির সাথে আমার সমস্যাটি হ'ল প্রতিনিধিকে কল করা ক্রাশের কারণ হয়ে দাঁড়ায় - EXC_BAD_ACCESS (অন্যত্র অন্যরা যেমন উল্লেখ করেছেন)) এটি বাগ বলে মনে হচ্ছে। আমি খুঁজে পেয়েছি একমাত্র সমাধান হ'ল @objc ব্যবহার করা এবং প্রোটোকল থেকে সমস্ত সুইফ্ট ডেটা ধরণের অপসারণ করা।
জিম টি

12
এখন সুইফটে দুর্বল প্রতিনিধিদের সঠিক পদ্ধতি কী? অ্যাপল ডকুমেন্টেশন প্রতিনিধিদের তাদের উদাহরণ কোডে দুর্বল হিসাবে দেখায় বা ঘোষণা করছে না: বিকাশকারী
অ্যাপ্লিকেশন

2
এটি সর্বদা নিরাপদ নয় - মনে রাখবেন যে প্রতিনিধিটির কোনও রেফারেন্সও যদি থাকে তবে আপনার কেবলমাত্র প্রতিনিধিটিকে দুর্বল করা দরকার এবং আপনাকে সেই শক্তিশালী রেফারেন্স চক্রটি ভাঙতে হবে। যদি প্রতিনিধিটির প্রতিনিধিটির কোনও রেফারেন্স না থাকে তবে ডেলিগেট সুযোগের বাইরে যেতে পারে (কারণ এটি দুর্বল) এবং আপনার ক্র্যাশ এবং অন্যান্য সমস্যা থাকতে হবে: / কিছু মনে রাখবেন।
ট্রেভ 14

5
বিটিডাব্লু: আমি মনে করি "নতুন স্টাইল" (সুইফ্ট 5) করতে হবে protocol ProtocolNameDelegate: AnyObject, তবে তাতে কিছু আসে যায় না।
এইচএনএইচ

1
এটি হতে হবে AnyObjectযেহেতু classকোনও পর্যায়ে হ্রাস করা হবে।
জোসে

283

পরিপূরক উত্তর

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

  • weakকীওয়ার্ডটি ব্যবহারের উদ্দেশ্য হ'ল শক্তিশালী রেফারেন্স চক্র এড়ানো (চক্র ধরে রাখা)। শক্তিশালী রেফারেন্স চক্র ঘটে যখন দুটি শ্রেণীর উদাহরণগুলির একে অপরের সাথে দৃ strong় উল্লেখ থাকে। তাদের রেফারেন্স গণনাগুলি কখনই শূন্যে যায় না তাই এগুলি কখনই বিঘ্নিত হয় না।

  • আপনার কেবলমাত্র weakপ্রতিনিধি শ্রেণি হলে ব্যবহার করতে হবে । সুইফ্ট স্ট্রাক্ট এবং এনামগুলি হ'ল মানের ধরণ (কোনও নতুন উদাহরণ তৈরি করার সময় তাদের মানগুলি অনুলিপি করা হয়), রেফারেন্স ধরণের নয়, তাই তারা দৃ strong ় রেফারেন্স চক্র তৈরি করে না ।

  • weakরেফারেন্সগুলি সর্বদা alচ্ছিক (অন্যথায় আপনি ব্যবহার করতেন unowned) এবং সর্বদা ব্যবহার করবেন var(না let) যাতে nilalচ্ছিকটি সেট আপ করা যায় যখন এটি নির্ধারণ করা হয়।

  • একটি পিতামাত্ত শ্রেণীর স্বাভাবিকভাবেই তার শিশু শ্রেণির একটি শক্তিশালী উল্লেখ থাকতে হবে এবং এইভাবে weakকীওয়ার্ডটি ব্যবহার করা উচিত নয় । যখন কোনও শিশু তার পিতামাতার কাছে কোনও রেফারেন্স চায়, তবে weakকীওয়ার্ডটি ব্যবহার করে এটির এটি দুর্বল রেফারেন্স করা উচিত ।

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

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

  • প্রোটোকলগুলি উভয় রেফারেন্স ধরণের (ক্লাস) এবং মান ধরণের (স্ট্রাক্টস, এনামগুলি) জন্য ব্যবহার করা যেতে পারে । সুতরাং সম্ভবত আপনার কোনও প্রতিনিধিকে দুর্বল করা দরকার, আপনাকে এটিকে কেবল একটি অবজেক্ট-প্রোটোকল তৈরি করতে হবে। এটি করার উপায় হ'ল AnyObjectপ্রোটোকলের উত্তরাধিকার তালিকায় যুক্ত হওয়া। (অতীতে আপনি classকীওয়ার্ডটি ব্যবহার করে এটি করেছিলেন তবে AnyObjectএখনই পছন্দ করা হয়েছে ))

    protocol MyClassDelegate: AnyObject {
        // ...
    }
    
    class SomeClass {
        weak var delegate: MyClassDelegate?
    }

আরও অধ্যয়ন

নিম্নলিখিত নিবন্ধগুলি পড়া যা আমাকে এটি আরও ভালভাবে বুঝতে সাহায্য করেছে। তারা unownedকীওয়ার্ড এবং বন্ধের সাথে ঘটে যাওয়া শক্তিশালী রেফারেন্স চক্রের মতো সম্পর্কিত বিষয়েও আলোচনা করে ।

সম্পর্কিত


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

30
তুমি ঠিক বলছো. আমি আসলে আপনার আগের মত একই প্রশ্ন ছিল, কিন্তু আমি এই পটভূমি তথ্য প্রচুর অনুপস্থিত। আমি আপনার উপরোক্ত পড়াটি করেছি এবং আপনার প্রশ্নের সাথে সম্পর্কিত সমস্ত বিষয় বুঝতে নিজেকে সাহায্য করার জন্য পরিপূরক নোট তৈরি করেছি। এখন আমি মনে করি আমি আপনার গৃহীত উত্তরটি প্রয়োগ করতে পারি এবং আমি কেন এটি করছি তা জানতে পারি। আমি আশা করি এটি সম্ভবত ভবিষ্যতের দর্শকদেরও সহায়তা করবে।
সুরগাচ

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

> কারণ বেশিরভাগ প্রতিনিধি ক্লাসগুলি উল্লেখ করে যাচ্ছেন যে তাদের নিজস্ব নেই আমি এটিকে আবার লিখব: বেশিরভাগ প্রতিনিধি। অন্যথায় মালিকানাধীন অবজেক্টটি মালিক হয়ে যায়
ভিক্টর জ্যালেন্সাস

36

AnyObject সুইফটে একটি দুর্বল রেফারেন্স ব্যবহারের সরকারী উপায়।

class MyClass {
    weak var delegate: MyClassDelegate?
}

protocol MyClassDelegate: AnyObject {
}

অ্যাপল থেকে:

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

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html#//apple_ref/doc/uid/TP40014097-CH25-ID276


7
মজাদার. হয় classসুইফট 4.1 উঠিয়ে?
এইচ এইচএন

@ এইচএনএইচ এখনও আপনি এটিকে একটি ক্লাস বানিয়ে একটি "সিউডো-প্রোটোকল" তৈরি করতে পারেন, তবে প্রোটোকল: অনিঅবজেক্ট ক্লাস তৈরির চেয়ে কম পার্শ্ব প্রতিক্রিয়া নিয়ে যা বলছে ঠিক তা করে। (আপনি এখনও মান প্রকারের সাথে এই জাতীয় প্রোটোকল ব্যবহার করতে পারবেন না, তবে এটির শ্রেণি ঘোষণা করে এটির কোনও সমাধান হবে না)
অরুর

8

আপডেট: দেখে মনে হচ্ছে ম্যানুয়ালটি আপডেট হয়েছে এবং আমি যে উদাহরণটির উল্লেখ করছি সেটি সরিয়ে ফেলা হয়েছে। উপরে @ ফ্লাইনজের উত্তরে সম্পাদনা দেখুন।

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


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

4
আমি মনে করি এটিও লক্ষণীয় যে \ @objc এর অতিরিক্ত পার্শ্ব প্রতিক্রিয়া রয়েছে - @ এক্সএক্সটেডের এনএসবজেক্টপ্রোটোকল পরামর্শটি আরও ভাল better Ob @objc- এর সাথে - যদি শ্রেণীর প্রতিনিধি কোনও 'হ্যান্ডেলসেলসুল্ট (r: মাইসুইফ্ট রিসাল্টক্লাস)' এর মতো কোনও বস্তুর যুক্তি গ্রহণ করে, মাইসইউফিটআরসাল্টক্লাসকে এখন এনএসবজেক্ট থেকে উত্তরাধিকারী হওয়া দরকার! সংক্ষেপে: ob @objc একটি ব্রিজিং বৈশিষ্ট্য, কোনও ভাষা নয়।
এইচএনএইচ

আমি মনে করি তারা এটি সমাধান করেছে। আপনি এখন লিখুন: প্রোটোকল মাইক্লাসডেলিগেট: শ্রেণি {}
ব্যবহারকারী 3675131

এ নিয়ে ডকুমেন্টেশন কোথায়? হয় আমি অন্ধ বা ভুল কিছু করছি, কারণ আমি এই সম্পর্কে কোনও তথ্য পাই না ...
O_O

আমি নিশ্চিত নই যে এটি ওপি-র প্রশ্নের জবাব দেয় কিনা, তবে এটি সহায়ক যদি বিশেষত আপনি ওজেসি-সি-তে হস্তক্ষেপ করছেন;)
ড্যান রোজনস্টার্ক

-1

প্রোটোকলটি অবশ্যই AnyObject, শ্রেণীর সাবক্লাস হতে হবে

নীচে দেওয়া উদাহরণ

    protocol NameOfProtocol: class {
   // member of protocol
    }
   class ClassName: UIViewController {
      weak var delegate: NameOfProtocol? 
    }

-9

অ্যাপল "ক্লাস" এর পরিবর্তে "এনএসবজেক্টপ্রোটোকল" ব্যবহার করে।

public protocol UIScrollViewDelegate : NSObjectProtocol {
   ...
}

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


5
প্রশ্নের জন্য প্রাসঙ্গিক নয়, এই প্রশ্নটি একটি ডেলিগেট অবজেক্টকে সমর্থন করে একটি খাঁটি সুইফ্ট ক্লাস (বিশেষত কোনও এনএসবজেক্ট নয়) তৈরির বিষয়ে। এটি অবজেক্টিভ-সি প্রোটোকলগুলি বাস্তবায়নের বিষয়ে নয়, যা আপনি করছেন। পরেরটির জন্য @objc ওরফে এনএসবজেক্টপ্রোটোকল প্রয়োজন।
এইচএনএম

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