প্রতিক্রিয়াশক্তি নির্বাচনকারীর সুইফ্ট সমতুল্য কী?


195

আমি গুগল করেছি তবে সুইফটের সমতুল্য কী তা খুঁজে বের করতে সক্ষম হইনি respondsToSelector:

এটি কেবলমাত্র জিনিস আমি খুঁজে পাইনি (হয় respondsToSelector করার সুইফট বিকল্প: ) কিন্তু তার প্রতিনিধি অস্তিত্ব চেক করার আমার ক্ষেত্রে খুব প্রাসঙ্গিক নয়, আমি একটি প্রতিনিধি আমি শুধু একটি নতুন API বিদ্যমান চেক করতে চান না বা ডিভাইসে চলাকালীন এবং এপিআই এর পূর্ববর্তী সংস্করণে ফিরে না এলে না।



নতুন অ্যাপ্লিকেশন কার্যকারিতা পরীক্ষা করার জন্য অ্যাপল স্পষ্টভাবে ব্যবহার করার জন্য NSClassFromStringএবং respondsToSelectorঅন্যান্য যান্ত্রিকগুলির মধ্যে সুপারিশ করার সাথে সাথে , আমি বিশ্বাস করতে পারি যে প্রক্রিয়াগুলি হয় ইতিমধ্যে কার্যকর ছিল, বা মুক্তি পাওয়ার আগে সেখানে থাকবে। Advanced Interop...ডাব্লুডাব্লুডিসি থেকে ভিডিওটি দেখার চেষ্টা করুন ।
ডেভিড বেরি

2
@ জ্যাক উ কিন্তু তবে যদি নতুন পদ্ধতিটি ইউআইএপ্লিকেশন বা ইউআইভিউকন্ট্রোলারের মতো মৌলিক কিছুতে নতুন কিছু চালু হয়। এই বিষয়গুলি alচ্ছিক নয় এবং নতুন পদ্ধতিটি alচ্ছিক নয়। আপনি যেমন ইউআইএপ্ল্যাফিকেশন: নিউ ভার্সনঅফমেথোডাক্সের জন্য অবশ্যই কল করতে পারেন তা আপনি কীভাবে চেক করতে পারেন বা আপনাকে অবশ্যই ইউআইএপ্লিকেশন: অবহেলিত ভার্সনঅফমেথডএক্স কল করতে হবে? (আপনি iOS 7 এ
সুইফটে

আপনি যে এপিআই / এর সাথে সম্পর্কিত ছিলেন তা কোনও অ্যাপল এপিআই এর সাথে সম্পর্কিত?
GoZoner

@ পটাসিয়ামপার্মাঙ্গানেট - অবশ্যই, যদি উত্তরটি হ্যাঁ, আমি অ্যাপল এপিআই ব্যবহার করছিলাম তবে সম্ভবত তিনি প্রথম স্থানে if #available(...)ব্যবহার এড়াতে সুইফট ২.x এ ব্যবহার করতে পারেন respondsToSelector। তবে আপনি তা জানতেন। ( Apple.co/1SNGtMQ )
GoZoner

উত্তর:


170

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

আপনার এখনও প্রয়োজন যেখানে প্রোটোকলের respondsToSelector:অংশ হিসাবে এটি এখনও আছে NSObject

আপনি যদি respondsToSelector:সুইফটে কোনও ওবজ-সি টাইপের কল করছেন, তবে এটি আপনার প্রত্যাশার মতোই কাজ করবে। আপনি যদি এটি নিজের সুইফ্ট ক্লাসে ব্যবহার করছেন তবে আপনার ক্লাসটি উদ্ভূত হয়েছে তা নিশ্চিত করতে হবে NSObject

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

class Worker : NSObject
{
    func work() { }
    func eat(food: AnyObject) { }
    func sleep(hours: Int, minutes: Int) { }
}

let worker = Worker()

let canWork = worker.respondsToSelector(Selector("work"))   // true
let canEat = worker.respondsToSelector(Selector("eat:"))    // true
let canSleep = worker.respondsToSelector(Selector("sleep:minutes:"))    // true
let canQuit = worker.respondsToSelector(Selector("quit"))   // false

এটি গুরুত্বপূর্ণ যে আপনি প্যারামিটারের নামগুলি ছেড়ে যাবেন না। এই উদাহরণে, Selector("sleep::")হয় না হিসাবে একই Selector("sleep:minutes:")


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

4
আপনাকে সেই লাইনগুলি বিভক্ত করতে হবে বাlet x = অংশটি সরিয়ে ফেলতে হবে । মূলত, if let x = yকাঠামোটি হ'ল alচ্ছিক মানগুলি (অনুরূপ !) মোড়ক করা । যেহেতু আপনি Boolফিরে পেয়ে respondsToSelectorযাচ্ছেন, সংকলক অভিযোগ করছে যে ফলাফলটি কোনও optionচ্ছিক ধরণের নয় ( Bool?)।
এরিক

এস কি হবে varঘোষিত? তারা এখনও কি একইভাবে প্রতিক্রিয়া? উদ্দেশ্য-সিতে আমি if ( [obj respondsToSelector:@selector(setSomeVar:)] ) { ... }কোনও someVarসম্পত্তির জন্য করতে পারি । এটি কী একইভাবে varসুইফটে এস এর সাথে কাজ করে ?
আলেজান্দ্রো ইভান

দেখুন যদি নিয়ামক দর্শন বিকল্পটি শূন্য না হয় তবে পদ্ধতি বা ফাংশনটি সেই নিয়ামকটিতে প্রয়োগ করা হয় না? আমি অনুমান করি যে আপনাকে নির্বাচককে প্রতিক্রিয়া জানায় কি না তা পরীক্ষা করে দেখুন।
আশীষ পিসে

আমি পাচ্ছি "ইউআইভিউউকন্ট্রোলারের ধরণের মানটির কোনও সদস্যই 'প্রতিক্রিয়াশক্তি নির্বাচন করেন না" "
মাইকা জিওব্রো

59

আসল সুইফ্ট রিপ্লেসমেন্ট নেই।

আপনি নিম্নলিখিত উপায়ে চেক করতে পারেন:

someObject.someMethod?()

এই পদ্ধতি কল someMethodশুধুমাত্র যদি এটা বস্তুর উপর সংজ্ঞায়িত হয়েছে তা someObjectকিন্তু আপনি শুধুমাত্র এটি ব্যবহার করতে পারেন @objcপ্রোটোকল যা পদ্ধতি ঘোষণা করেছেন optional

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

এমনকি ওজেজে-সিতে আপনার যখন সম্ভব হয় তখন এ জাতীয় জিনিসগুলি এড়ানো উচিত কারণ এটি আরসি (টিআরসি এর পরে সতর্কতার সূত্রপাত করে performSelector:) দিয়ে ভাল না খায় ।

যাইহোক, উপলভ্য API গুলি সন্ধানের সময় আপনি respondsToSelector:যদি সুইফট ব্যবহার করেন তবে আপনি NSObjectউদাহরণগুলির সাথে কাজ করছেন:

@interface TestA : NSObject

- (void)someMethod;

@end

@implementation TestA

//this triggers a warning

@end   


var a = TestA()

if a.respondsToSelector("someMethod") {
   a.someMethod()
}

1
সুতরাং অ্যাপ্লিকেশনগুলিকে এখন স্পষ্টভাবে জানতে হবে যে তারা ওএসের কোন সংস্করণ চলছে? আমি এমন একটি পদ্ধতিতে কল করতে চাই যা কেবল iOS8 এ বিদ্যমান এবং যদি এটি না থাকে তবে পুরানো iOS7 সংস্করণ ব্যবহার করা যায়। সুতরাং নতুন পদ্ধতির উপস্থিতি / অনুপস্থিতता পরীক্ষা করার পরিবর্তে আমি অনুসন্ধান করতে হবে আমি iOS8 এ আছি কিনা? সুইফট ভাল তবে এটিকে কিছুটা জটিল বলে মনে হচ্ছে।
গ্রানটেকস

@ সুলতান আমি নিশ্চিত নই আপনি কোথা থেকে এসেছেন তা জানিয়ে আপনি যে respondsToSelector:অ্যাপলের প্রস্তাবনাটি স্পষ্টভাবে বোঝাচ্ছেন যে আপনার এটি করা উচিত। এখানে
ডেভিড বেরি

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

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

1
@ মধু সুইফটে আমরা সাধারণত পরিবর্তে প্রাপ্যতা নির্দেশাবলী ব্যবহার করি, উদাহরণস্বরূপ if #available(iOS 10) {এবং তারপরে সরাসরি পদ্ধতিটিতে কল করুন।
সুলতান

40

সুইফট 3 সিনট্যাক্সের জন্য মার্চ 20, 2017 আপডেট করুন:

Youচ্ছিক পদ্ধতিটি বিদ্যমান কিনা তা যদি আপনি যত্ন না করেন তবে কেবল কল করুন delegate?.optionalMethod?()

অন্যথায়, guardসম্ভবত ব্যবহার করা সর্বোত্তম পন্থা:

weak var delegate: SomeDelegateWithOptionals?

func someMethod() {
    guard let method = delegate?.optionalMethod else {
        // optional not implemented
        alternativeMethod()
        return
    }
    method()
}

আসল উত্তর:

আপনি এইভাবে একটি alচ্ছিক প্রোটোকল পরীক্ষা করতে "if let" পদ্ধতির ব্যবহার করতে পারেন:

weak var delegate: SomeDelegateWithOptionals?

func someMethod() {
  if let delegate = delegate {
    if let theMethod = delegate.theOptionalProtocolMethod? {
      theMethod()
      return
    }
  }
  // Reaching here means the delegate doesn't exist or doesn't respond to the optional method
  alternativeMethod()
}

4
যদি মেঠোড = প্রতিনিধি দেওয়া যায়?? ption
চ্ছিক প্রোটোকল

1
একাধিক প্রার্থী থাকাকালীন নির্বাচক সিনট্যাক্সের উদাহরণ:let theMethod = delegate.userNotificationCenter(_:willPresent:withCompletionHandler:)
সিউর

11

মনে হচ্ছে আপনার প্রোটোকলটিকে এনএসওজেটপ্রোটোকলের সাবপ্রোটোকল হিসাবে সংজ্ঞায়িত করা দরকার ... তারপরে আপনি প্রতিক্রিয়া পাবেন

@objc protocol YourDelegate : NSObjectProtocol
{
    func yourDelegateMethod(passObject: SomeObject)
}

মনে রাখবেন যে কেবলমাত্র @objc উল্লেখ করা যথেষ্ট ছিল না। আপনার অবশ্যই সতর্ক হওয়া উচিত যে প্রকৃত প্রতিনিধিটি এনএসবজেক্টের একটি সাবক্লাস - যা সুইফ্টে নাও হতে পারে।


10

আপনি যে পদ্ধতিটির জন্য পরীক্ষা করছেন সেটি যদি একটি হিসাবে সংজ্ঞায়িত হয় ঐচ্ছিক পদ্ধতি একটি @objc প্রটোকল (যা আপনার কেস মত শোনাচ্ছে), তারপর ব্যবহার ঐচ্ছিক chaining যেমন প্যাটার্ন:

if let result = object.method?(args) {
  /* method exists, result assigned, use result */
}
else { ... }

পদ্ধতিটি যখন প্রত্যাবর্তন হিসাবে ঘোষণা করা হয় Void, কেবল ব্যবহার করুন:

if object.method?(args) { ... }

দেখা:

"Cha
চ্ছিক চেইনের মাধ্যমে কলিং পদ্ধতিগুলি" এর সংক্ষেপণ: অ্যাপল ইনক। "দ্য সুইফ্ট প্রোগ্রামিং ভাষা।"
iBooks। https://itun.es/us/jEUH0.l


এটি কেবল তখনই কাজ করবে যদি পদ্ধতিটি কোনও কিছু ফেরত দেয়, যদি এটি একটি শূন্য পদ্ধতি হয়?
গ্রানটেকস

1
যদি অকার্যকরভাবে সহজভাবে ব্যবহার করা হয় if object.method?(args) { ... }- পদ্ধতিটির কল, এটি বিদ্যমান থাকলে ফিরে আসবে Voidযা নেইnil
GoZoner

1
তবে "টাইপ অকার্যকর" এর ফলাফলগুলি প্রোটোকল "লজিক মান" এর সাথে সামঞ্জস্য করে না "
গ্রানটেকস

দয়া করে রেফারেন্সড ডকুমেন্টেশন (পৃষ্ঠা 311-312) দেখুন।
GoZoner

"আপনি যে পদ্ধতিটির জন্য পরীক্ষা করছেন সেটি যদি একটি @objc প্রোটোকলে একটি alচ্ছিক পদ্ধতি হিসাবে সংজ্ঞায়িত করা হয়" বা যদি objectএর টাইপ থাকে তবে AnyObjectআপনি কোনও @objc পদ্ধতি পরীক্ষা করতে পারেন।
newacct

9

কার্যগুলি সুইফটে প্রথম শ্রেণীর ধরণের, তাই আপনি কোনও প্রোটোকলে সংজ্ঞায়িত optionচ্ছিক ফাংশনটি শূন্যের সাথে তুলনা করে প্রয়োগ করা হয়েছে কিনা তা পরীক্ষা করতে পারেন:

if (someObject.someMethod != nil) {
    someObject.someMethod!(someArgument)
} else {
    // do something else
}

1
পদ্ধতিটি যদি বোঝা হয়? আমরা কীভাবে একটি নির্দিষ্টটির জন্য পরীক্ষা করতে পারি?
নুনো গোনালভেস

8

সুইফট 3 এর জন্য

আপনি যদি কেবল পদ্ধতিটি কল করতে চান তবে নীচের কোডটি চালান।

self.delegate?.method?()


7

সুইফট 2, অ্যাপল নামক একটি নতুন বৈশিষ্ট্য চালু API availability checking, যার জন্য একটি প্রতিস্থাপন হতে পারে respondsToSelector:কোড স্নিপেট তুলনা নিম্নলিখিত method.The WWDC2015 সেশন 106 থেকে অনুলিপি করা হয়েছে কি সুইফট নতুন যা আমি তোমাদের সাহায্য করতে পারে চিন্তা, দয়া করে এটি চেক আউট যদি আপনি প্রয়োজন আরও জানুন।

পুরানো পদ্ধতির:

@IBOutlet var dropButton: NSButton!
override func awakeFromNib() {
    if dropButton.respondsToSelector("setSpringLoaded:") {
        dropButton.springLoaded = true
    }
}

আরও ভাল পদ্ধতি:

@IBOutlet var dropButton: NSButton!
override func awakeFromNib() {
    if #available(OSX 10.10.3, *) {
        dropButton.springLoaded = true
    }
}

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

6

দ্রুত 3.0

import UIKit

@objc protocol ADelegate : NSObjectProtocol {

    @objc optional func hi1()
    @objc optional func hi2(message1:String, message2:String)
}

class SomeObject : NSObject {

    weak var delegate:ADelegate?

    func run() {

        // single method
        if let methodHi1 = delegate?.hi1 {
            methodHi1()
        } else {
            print("fail h1")
        }

        // multiple parameters
        if let methodHi2 = delegate?.hi2 {
            methodHi2("superman", "batman")
        } else {
            print("fail h2")
        }
    }
}

class ViewController: UIViewController, ADelegate {

    let someObject = SomeObject()

    override func viewDidLoad() {
        super.viewDidLoad()

        someObject.delegate = self
        someObject.run()
    }

    // MARK: ADelegate
    func hi1() {

        print("Hi")
    }

    func hi2(message1: String, message2: String) {

        print("Hi \(message1) \(message2)")
    }
}

4

বর্তমানে (সুইফট ২.১) আপনি এটি 3 টি উপায় ব্যবহার করে পরীক্ষা করতে পারেন:

  1. @ এরিক_্যাট_ডিজ্ট দ্বারা জবাব দেওয়া টোটোসিলেক্টর ব্যবহার করে
  2. ব্যবহার করছেন ? ' উত্তর দিয়েছেন সুলতান

  3. এবং as?অপারেটর ব্যবহার :

    if let delegateMe = self.delegate as? YourCustomViewController
    {
       delegateMe.onSuccess()
    }

মূলত এটি আপনি কী অর্জন করতে চাইছেন তার উপর নির্ভর করে:

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

2

আমি কেবল একটি প্রকল্পে এটি প্রয়োগ করি, নীচের কোডটি দেখুন। @ ক্রিস্টোফার পিকস্লে দ্বারা উল্লেখ করা হিসাবে এটি মনে রাখা গুরুত্বপূর্ণ যে ফাংশনগুলি প্রথম শ্রেণির নাগরিক এবং তাই optionচ্ছিক পরিবর্তনশীলগুলির মতো আচরণ করা যেতে পারে।

@objc protocol ContactDetailsDelegate: class {

    optional func deleteContact(contact: Contact) -> NSError?
}

...

weak var delegate:ContactDetailsDelegate!

if let deleteContact = delegate.deleteContact {
    deleteContact(contact)
}

পদ্ধতিটি যদি বোঝা হয়? কেউ কীভাবে তা করবে?
নুনো গোনালভেস

2

দ্রুত সম্ভব অন্য বাক্য গঠন

 if let delegate = self.delegate, method = delegate.somemethod{
        method()
    }

2

আমি আমার পুরানো প্রকল্পটি সুইফট ৩.২ এ আপডেট করতে শুরু করার সাথে সাথে আমার কেবল পদ্ধতিটি পরিবর্তন করা দরকার

respondsToSelector(selector)

প্রতি:

responds(to: selector)

0

আমি ব্যবহার করি guard let else, যাতে ডেলিগেট ফানক প্রয়োগ না করা হলে এটি কিছু ডিফল্ট জিনিসগুলি করতে পারে।

@objc protocol ViewController2Delegate: NSObjectProtocol {

    optional func viewController2(controller: ViewController2, didSomethingWithStringAndReturnVoid string: String)

    optional func viewController2(controller: ViewController2, didSomethingWithStringAndReturnString string: String) -> String
}

class ViewController2: UIViewController {

    weak var delegate: ViewController2Delegate?        

    @IBAction func onVoidButtonClicked(sender: AnyObject){

        if (delegate != nil && delegate!.respondsToSelector(Selector("viewController2:didSomethingWithStringAndReturnVoid:"))) {
            NSLog("ReturnVoid is implemented")

            delegate!.viewController2!(self, didSomethingWithStringAndReturnVoid: "dummy")
        }
        else{
            NSLog("ReturnVoid is not implemented")
            // Do something by default
        }
    }

    @IBAction func onStringButtonClicked(sender: AnyObject){

        guard let result = delegate?.viewController2?(self, didSomethingWithStringAndReturnString: "dummy") else {
            NSLog("ReturnString is not implemented")
            // Do something by default
            return
        }

        NSLog("ReturnString is implemented with result: \(result)")
    }
}

-1

সুইফট 3:

প্রোটোকল

@objc protocol SomeDelegate {
    @objc optional func method()
}

উদ্দেশ্য

class SomeObject : NSObject {

weak var delegate:SomeObject?

func delegateMethod() {

     if let delegateMethod = delegate?.method{
         delegateMethod()
     }else {
        //Failed
     }

   }

}

-4

সমান? অপারেটর:

var value: NSNumber? = myQuestionableObject?.importantMethod()

গুরুত্বপূর্ণ মেঠোড কেবল তখনই কল করা হবে যদি মাইকিউশনেশনঅবজেক্ট উপস্থিত থাকে এবং এটি প্রয়োগ করে।


তবে মাইকিউসিশনালঅবজেক্টটি যদি ইউআইএপ্লিকেশন (যা অতএব বিদ্যমান রয়েছে এবং সুতরাং এর অস্তিত্ব পরীক্ষা করা অর্থহীন) এবং ইমপোর্ট্যান্ড ম্যাথোড () আইওএস এন এ প্রবর্তিত একটি নতুন পদ্ধতি এবং আপনি এটি নির্ধারণ করতে চান বা কল করতে হবে কিনা তা নির্ধারণ করতে চান আইওএস এন -1 এ পুরনো অবহেলাবিহীনমৈথোড ()?
গ্রানটেকস

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