সুইফ্ট alচ্ছিক বন্ধের প্যারামিটার পলায়ন


162

প্রদত্ত:

typealias Action = () -> ()

var action: Action = { }

func doStuff(stuff: String, completion: @escaping Action) {
    print(stuff)
    action = completion
    completion()
}

func doStuffAgain() {
    print("again")
    action()
}

doStuff(stuff: "do stuff") { 
    print("swift 3!")
}

doStuffAgain()

completionপরামিতি (এবং action) টাইপ করার Action?এবং রাখার কি কোনও উপায় আছে @escaping?

প্রকারটি পরিবর্তন করা নিম্নলিখিত ত্রুটিটি দেয়:

@ এস্কেপিং এ্যাট্রিবিউট কেবল ফাংশনের ধরণের ক্ষেত্রে প্রযোজ্য

সরানো হচ্ছে @escapingঅ্যাট্রিবিউট, কোড প্রনয়ন এবং রান কিন্তু যেহেতু সঠিক হতে বলে মনে হচ্ছে না completionঅবসান ফাংশন সুযোগ পলায়নের হয়।


21
"মুছে ফেলার পদ্ধতি @escapingঅ্যাট্রিবিউট, কোড প্রনয়ন এবং রান" - কারণ বর্ণনা অনুযায়ী যে এসআর-2444 , Action?, ডিফল্টরূপে, পলায়নপর হয়। সুতরাং, @escapingclosureচ্ছিক বন্ধ ব্যবহার করার সময় অপসারণ করা আপনার প্রয়োজনীয়গুলি পূরণ করে।
রব


টাইপ ওরফে ক্লোজারগুলি পালাচ্ছে
মসিহ

এখানে ওলে বেগম্যানের একটি দুর্দান্ত নিবন্ধ রয়েছে যা এটি কেন ঘটছে তা বর্ণনা করে এবং যদি আপনি noচ্ছিক প্যারামিটারগুলি @ ননস্কেপ হতে চান তবে কিছু কর্মক্ষেত্র রয়েছে describes
সংবেদনশীল

উত্তর:


122

এখানে একটি এসআর -2552 প্রতিবেদন রয়েছে যা @escapingফাংশন প্রকারের ওরফে স্বীকৃতি দেয় না। যে কারণে ত্রুটি @escaping attribute only applies to function types। আপনি ফাংশনের স্বাক্ষরে ফাংশনের ধরণটি প্রসারিত করে কাজ করতে পারেন:

typealias Action = () -> ()

var action: Action? = { }

func doStuff(stuff: String, completion: (@escaping ()->())?) {
    print(stuff)
    action = completion
    completion?()
}

func doStuffAgain() {
    print("again")
    action?()
}

doStuff(stuff: "do stuff") {
    print("swift 3!")
}

doStuffAgain()

সম্পাদনা 1 :

আমি আসলে একটি এক্সকোড 8 বিটা সংস্করণের অধীনে ছিলাম যেখানে বাগ SR-2552 এখনও সমাধান হয়নি। এই বাগটি ঠিক করা, একটি নতুন প্রবর্তন করা (আপনি যার মুখোমুখি হচ্ছেন) এটি এখনও খোলা আছে। দেখতে এসআর-2444

কার্যসংক্রান্ত @Michael Ilseman একটি অস্থায়ী সমাধান হিসেবে উল্লেখ অপসারণ হয় @escapingঐচ্ছিক ফাংশন ধরণ থেকে গুণ, যে পলায়নপর যেমন ফাংশন রাখা

func doStuff(stuff: String, completion: Action?) {...}

সম্পাদনা 2 :

এসআর-2444 বন্ধ হয়ে স্পষ্টভাবে জানায় যে পরামিতি অবস্থানকে বন্ধ হয় না পলায়নের এবং চিহ্নিত করা তাদের প্রয়োজন @escapingতাদের পলায়নের করতে, কিন্তু ঐচ্ছিক প্যারামিটার হয় পরোক্ষভাবে পলায়নের, যেহেতু ((Int)->())?একটি প্রতিশব্দের হয় Optional<(Int)->()>, ঐচ্ছিক বন্ধ পলায়নপর করছে।


5
এখন পাচ্ছেন@escaping may only be applied to parameters of function type func doStuff(stuff: String, completion: (@escaping ()->())?) {
লেসকাই আয়নেল

1
a temporary solution is remove the @escaping attribute from optional function type, that keep the function as escaping. আপনি এই আরও ব্যাখ্যা করতে পারেন? সুইফ্ট 3-এ ডিফল্ট অর্থসূচকটি হ'ল অ-পলায়ন। যদিও এটি @ ছাড়ার ব্যতীত সংকলন করেছে আমি ভয় করি যে এটি পলায়নবিহীন হিসাবে আচরণ করে সমস্যা সৃষ্টি করবে। এটা কি সত্য নয়?
প্যাট নিমিমায়ার

49
আরও পড়ার পরে আমি দেখতে পাচ্ছি যে এসআর -৪৪৪৪ বলেছে যে সমস্ত বিকল্প clos
প্যাট নিমিমায়ার

কিছুটা বন্ধ বিষয় হতে পারে; কিন্তু কিভাবে এই কাজ করে @autoclosure? একজন সেখানে একই ত্রুটি পেয়ে যায় ...
Gee.E

এটি @ এস্কেপিং ছাড়াই কাজ করছে __ ফানক ডু স্টাফ (স্টাফ: স্ট্রিং, সমাপ্তি: (() -> ())?) {
Мезитов

226

থেকে: দ্রুত ব্যবহারকারীদের মেলিং তালিকা

মূলত, @ এস্কেপিং কেবলমাত্র ফাংশন প্যারামিটার পজিশনে ক্লোজারে বৈধ। নোসকেপ-বাই-ডিফল্ট নিয়ম কেবল ফাংশন প্যারামিটার পজিশনে এই ক্লোজারগুলিতে প্রযোজ্য, অন্যথায় তারা পালাচ্ছে। সমষ্টি, যেমন সম্পর্কিত মানগুলির সাথে এনামগুলি (যেমন ptionচ্ছিক), টিপলস, স্ট্রাক্টস, ইত্যাদির যদি ক্লোজার থাকে তবে ফাংশন প্যারামিটার পজিশনে নেই এমন ক্লোজারগুলির জন্য ডিফল্ট নিয়মগুলি অনুসরণ করুন, অর্থাৎ তারা পালিয়ে যাচ্ছে।

সুতরাং alচ্ছিক ফাংশন প্যারামিটারটি ডিফল্টরূপে @caping হয়।
@ নোনাস্কেপ কেবলমাত্র ডিফল্টরূপে ফাংশন প্যারামিটারে প্রয়োগ হয়।


7
আমি মনে করি এটি বিষয়টিতে সবচেয়ে গুরুত্বপূর্ণ তথ্য যুক্ত করে, এটি উত্তর গ্রহণ করা উচিত।
দামিয়ান ডুডিক্স 22:38

যুক্তিযুক্ত উত্তর। এটি সম্ভবত যে এটি পরিবর্তন হতে পারে?
গোল্ডেনজো

2
প্রযুক্তিগতভাবে বলা (()->Void)?আপনার কাছে বলার মতো Optional<()->Void>এবং Optionalএটির মালিকানা বজায় রাখার জন্য এটি কেবল @escapingফাংশন স্বীকার করতে হবে বলে এটি বোধগম্য হয়। আমি তৃতীয় করব যে এটি গ্রহণযোগ্য উত্তর হওয়া উচিত। ধন্যবাদ.
ডিন কেলি

22

আমি একটি অনুরূপ সমস্যার মধ্যে দৌড়েছি কারণ মিশ্রণ @escapingএবং অ- @escapingখুব বিভ্রান্তিকর, বিশেষত যদি আপনার চারপাশে ক্লোজারগুলি পাস করার প্রয়োজন হয়।

আমি ক্লোজার প্যারামিটারের মাধ্যমে কোনও অপ-ডিফল্ট মান নির্ধারণ করে শেষ করেছি = { _ in }, যা আমি মনে করি যে এটি আরও অর্থবোধ করে:

func doStuff(stuff: String = "do stuff",
        completion: @escaping (_ some: String) -> Void = { _ in }) {
     completion(stuff)
}

doStuff(stuff: "bla") {
    stuff in
    print(stuff)
}

doStuff() {
    stuff in
    print(stuff)
}

এটি কার্যকর এবং বাস্তবায়নে বেশ সুন্দর।
ফ্রেড ফাউস্ট

2
আমি যদি এই ব্লকটি শূন্য / খালি খালি দেখতে চাই তবে কী হবে?
ভাইচাসলভ গের্চিকভ

2
বামার, এটি প্রোটোকল পদ্ধতির জন্য কাজ করে না। "প্রোটোকল পদ্ধতিতে ডিফল্ট যুক্তি অনুমোদিত নয়" (এক্সকোড 8.3.2)।
মাইক তাভারনে

17

আমি এটিকে কোনও সতর্কীকরণ ছাড়াই কেবল সুইফট 3 এ কাজ করতে শুরু করেছি:

func doStuff(stuff: String, completion: (()->())? ) {
    print(stuff)
    action = completion
    completion?()
}

4

উদাহরণে বুঝতে গুরুত্বপূর্ণ বিষয় যে যদি আপনি পরিবর্তন হয় Actionকরার Action?অবসান হয় পলায়নের। সুতরাং, আসুন আপনি যা প্রস্তাব দিন:

typealias Action = () -> ()

var action: Action? = { }

func doStuff(stuff: String, completion: Action?) {
    print(stuff)
    action = completion
    completion?()
}

ঠিক আছে, এখন আমরা কল করব doStuff:

class ViewController: UIViewController {
    var prop = ""
    override func viewDidLoad() {
        super.viewDidLoad()
        doStuff(stuff: "do stuff") {
            print("swift 3!")
            print(prop) // error: Reference to property 'prop' in closure 
                        // requires explicit 'self.' to make capture semantics explicit
        }
    }
}

ঠিক আছে, এই প্রয়োজনীয়তাটি কেবল ক্লোসারের হাত থেকে বাঁচার জন্যই উদ্ভূত হয়। তাই বন্ধটি পালাচ্ছে। এজন্য আপনি এটিকে পালানোর চিহ্ন হিসাবে চিহ্নিত করেন না - এটি ইতিমধ্যে পালাচ্ছে।

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