সুইফটে ফাংশন প্যারামিটার হিসাবে প্রোটোকল অনুসারে ক্লাস


91

অবজেক্টিভ-সি-তে, কোনও পদ্ধতি পরামিতি হিসাবে কোনও প্রোটোকলের সাথে সঙ্গতিপূর্ণ কোনও শ্রেণি নির্দিষ্ট করা সম্ভব। উদাহরণস্বরূপ, আমার কাছে এমন একটি পদ্ধতি থাকতে পারে যা কেবলমাত্র UIViewControllerতার সাথে সঙ্গতিপূর্ণ হয় UITableViewDataSource:

- (void)foo:(UIViewController<UITableViewDataSource> *)vc;

আমি সুইফটে এটি করার কোনও উপায় খুঁজে পাচ্ছি না (সম্ভবত এটি এখনও সম্ভব নয়)। আপনি একাধিক প্রোটোকল ব্যবহার করে নির্দিষ্ট করতে পারেন func foo(obj: protocol<P1, P2>), তবে কীভাবে আপনার প্রয়োজন হয় যে অবজেক্টটিও একটি নির্দিষ্ট শ্রেণির হয়?


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

উত্তর:


133

আপনি fooজেনেরিক ফাংশন হিসাবে সংজ্ঞায়িত করতে পারেন এবং ক্লাস এবং প্রোটোকল উভয়ের জন্যই টাইপ সীমাবদ্ধতাগুলি ব্যবহার করতে পারেন।

সুইফট 4

func foo<T: UIViewController & UITableViewDataSource>(vc: T) {
    .....
}

সুইফট 3 (সুইফট 4 এর জন্যও কাজ করে)

func foo<T: UIViewController>(vc:T) where T:UITableViewDataSource { 
    ....
}

সুইফট 2

func foo<T: UIViewController where T: UITableViewDataSource>(vc: T) {
    // access UIViewController property
    let view = vc.view
    // call UITableViewDataSource method
    let sections = vc.numberOfSectionsInTableView?(tableView)
}

4
আমি মনে করি এটি একটু দুর্ভাগ্যজনক যে এটি প্রয়োজন। আশা করি ভবিষ্যতে এর জন্য একটি ক্লিনার সিনট্যাক্স থাকবে যেমন protocol<>সরবরাহ করে (তবে protocol<>নন-প্রোটোকল টাইপ থাকতে পারে না)।
jtbandes

এতে আমার খুব খারাপ লাগছে।
ডিসিম্যাক্সেক্সেক্স

কৌতূহলের মাত্র বাইরে, আপনি numberOfSectionsInTableViewপ্রয়োজনীয়ভাবে ফাংশন মোড়ানো করতে পারবেন না কারণ এটি প্রয়োজনীয় ফাংশনটিতে রয়েছে UITableViewDataSource?
rb612

numberOfSectionsInTableView:alচ্ছিক — আপনি হয়ত ভাবছেন tableView:numberOfRowsInSection:
নেট কুক

11
সুইফ্ট 3 এ এটি Xcode 8 বিটা 6 হিসাবে অগ্রাধিকার সহ অবচিত বলে মনে হচ্ছে:func foo<T: UIViewController>(vc:T) where T:UITableViewDataSource { ... }
LOP_Luke


17

সুইফট বুক ডকুমেন্টেশনটি পরামর্শ দেয় যে আপনি যেখানে একটি ধারা দিয়ে টাইপ সীমাবদ্ধতা ব্যবহার করেছেন:

func someFunction<C1: SomeClass where C1:SomeProtocol>(inParam: C1) {}

এটি গ্যারান্টি দেয় যে "ইনপ্যারাম" "সামারক্লাস" টাইপযুক্ত শর্ত সহ এটি "সামারপ্রোটোকল" মেনে চলে। এমন কি এমন একাধিক নির্দিষ্ট করার ক্ষমতাও রয়েছে যেখানে কমা দ্বারা বিধি বিযুক্ত করা হয়েছে:

func itemsMatch<C1: SomeProtocol, C2: SomeProtocol where C1.ItemType == C2.ItemType,    C1.ItemType: SomeOtherProtocol>(foo: C1, bar: C2) -> Bool { return true }

4
ডকুমেন্টেশনের লিঙ্কটি দেখতে ভাল লাগত।
রাজ

4

সুইফট 3 এর সাহায্যে আপনি নিম্নলিখিতটি করতে পারেন:

func foo(_ dataSource: UITableViewDataSource) {
    self.tableView.dataSource = dataSource
}

func foo(_ delegateAndDataSource: UITableViewDelegate & UITableViewDataSource) { 
    //Whatever
}

4
এটি কেবল প্রোটোকলগুলিতেই প্রযোজ্য, প্রোটোকল ও দ্রুতগতিতে ক্লাস 3
আর্টেম গোরিয়েভ


2

এই উপায় সম্পর্কে কি ?:

protocol MyProtocol {
    func getTableViewDataSource() -> UITableViewDataSource
    func getViewController() -> UIViewController
}

class MyVC : UIViewController, UITableViewDataSource, MyProtocol {

    // ...

    func getTableViewDataSource() -> UITableViewDataSource {
        return self
    }

    func getViewController() -> UIViewController {
        return self
    }
}

func foo(_ vc:MyProtocol) {
    vc.getTableViewDataSource() // working with UITableViewDataSource stuff
    vc.getViewController() // working with UIViewController stuff
}

0

২০১৫ সালের সেপ্টেম্বরে নোট : এটি সুইফ্টের প্রথম দিকের পর্যবেক্ষণ ছিল।

এটা অসম্ভব বলে মনে হচ্ছে। অ্যাপল এর কিছু এপিআইতেও এই বিরক্তি রয়েছে। আইওএস 8-এ সদ্য চালু হওয়া শ্রেণীর একটি উদাহরণ এখানে রয়েছে (বিটা 5 হিসাবে):

UIInputViewControllerএর textDocumentProxyসম্পত্তি:

নিম্নরূপ উদ্দেশ্য-সি সংজ্ঞায়িত:

@property(nonatomic, readonly) NSObject<UITextDocumentProxy> *textDocumentProxy;

এবং সুইফটে:

var textDocumentProxy: NSObject! { get }

অ্যাপলের ডকুমেন্টেশনের লিঙ্ক: https://developer.apple.com/library/prerelease/iOS/docamentation/UIKit/References/UIInputViewController_Class/index.html#//apple_ref/occ/instp/UIInputViewController/textDocamentProxy


4
এটি স্বয়ংক্রিয়ভাবে উত্পাদিত বলে মনে হচ্ছে: সুইফ্ট প্রোটোকলগুলি বস্তু হিসাবে প্রায় পাস হতে পারে। তাত্ত্বিকভাবে তারা কেবল টাইপ করতে পারেvar textDocumentProxy: UITextDocumentProxy! { get }
atlex2

@ অ্যাটলেক্স 2 আপনি ইউআইটিএক্সটেক্সট ডকুমেন্টপ্রক্সি প্রোটোকল প্রকারের পক্ষে এনএসবজেক্ট শ্রেণীর প্রকারটি হারিয়েছেন।
টাইটানিয়ামডেকয়

@titaniumdecoy না আপনি ভুল করছেন; আপনার যদি এখনও ইউআইটিেক্সটডকুমেন্টপ্রক্সিকে বেশিরভাগ প্রোটোকলের মতো ঘোষণা করা হয় তবে আপনার কাছে এনএসবজেক্ট রয়েছে:@protocol MyAwesomeCallbacks <NSObject>
কমাটওস্ট

@ কমমাটোস্ট সুইফটে নয়, যা এই প্রশ্নটি সম্পর্কে।
টাইটানিয়ামডেকয়

@ টাইটানিয়ামডেকয় হ্যাঁ, আপনি আদি থেকেই ছিলেন আমি বিভ্রান্ত ছিলাম! আপনার ভুল ছিল বলে দুঃখিত। উল্টোদিকে আপনার কাছে এখনও এনএসবজেক্টপ্রোটোকল রয়েছে ... এই উদাহরণে ... তবে আমি জানি এটি একই জিনিস নয়।
কমাটোস্ট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.