আমি কীভাবে প্রেরণ_পরে জিসিডি সুইফট 3, 4, এবং 5 এ লিখব?


445

সুইফট 2-এ, আমি dispatch_afterগ্র্যান্ড সেন্ট্রাল প্রেরণ ব্যবহার করে কোনও ক্রিয়ায় বিলম্ব করতে সক্ষম হয়েছি :

var dispatchTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC))) 
dispatch_after(dispatchTime, dispatch_get_main_queue(), { 
    // your function here 
})

তবে এটি আর সুইফট ৩-এর পরে সংকলিত বলে মনে হচ্ছে না আধুনিক সুইফটে এটি লেখার পছন্দের উপায়টি কী?


6
মাইগ্রেশন প্রক্রিয়া সম্পর্কে আরও তথ্য এখানে পাওয়া যাবে: https://swift.org/migration-guide/ "প্রেরণ" বিভাগটি এই প্রশ্নের জন্য প্রাসঙ্গিক
টোনিক 12

আপনার প্রশ্ন করা উচিত UInt64?
মধু 20

উত্তর:


1125

বাক্য গঠনটি সহজভাবে:

// to run something in 0.1 seconds

DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
    // your code here
}

দ্রষ্টব্য, উপরের সিনট্যাক্সটিকে secondsএকটি হিসাবে Doubleবিভ্রান্তির উত্স হিসাবে মনে হচ্ছে (যেমন আমরা এনসিএসি যুক্ত করতে অভ্যস্ত ছিলাম)। Doubleসিনট্যাক্সটি " সেকেন্ড যুক্ত হিসাবে " কাজ করে কারণ deadlineএকটি DispatchTimeএবং পর্দার পিছনে এমন একটি +অপারেটর রয়েছে যা এটি গ্রহণ করবে Doubleএবং এতে অনেক সেকেন্ড যোগ করবে DispatchTime:

public func +(time: DispatchTime, seconds: Double) -> DispatchTime

কিন্তু, আপনি যদি সত্যিই msec μs, অথবা nsec এর একটি পূর্ণসংখ্যা সংখ্যা যোগ করতে চান DispatchTime, তবে আপনাকে একটি যোগ করতে পারেন DispatchTimeIntervalএকটি থেকে DispatchTime। এর অর্থ আপনি করতে পারেন:

DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) {
    os_log("500 msec seconds later")
}

DispatchQueue.main.asyncAfter(deadline: .now() + .microseconds(1_000_000)) {
    os_log("1m μs seconds later")
}

DispatchQueue.main.asyncAfter(deadline: .now() + .nanoseconds(1_500_000_000)) {
    os_log("1.5b nsec seconds later")
}

ক্লাসে +অপারেটরের জন্য এই পৃথক ওভারলোড পদ্ধতির কারণে এগুলি সমস্ত নির্বিঘ্নে কাজ করে DispatchTime

public func +(time: DispatchTime, interval: DispatchTimeInterval) -> DispatchTime

এটি জিজ্ঞাসা করা হয়েছিল যে কীভাবে একজন প্রেরণ করা টাস্ক বাতিল করার বিষয়ে যায়। এটি করতে, ব্যবহার করুন DispatchWorkItem। উদাহরণস্বরূপ, এটি এমন একটি কাজ শুরু করে যা পাঁচ সেকেন্ডের মধ্যেই আগুন নেবে, বা যদি ভিউ কন্ট্রোলারকে বরখাস্ত করে এবং deinitবাতিল করা হয়, তবে এটি কার্যটি বাতিল করে দেবে:

class ViewController: UIViewController {

    private var item: DispatchWorkItem?

    override func viewDidLoad() {
        super.viewDidLoad()

        item = DispatchWorkItem { [weak self] in
            self?.doSomething()
            self?.item = nil
        }

        DispatchQueue.main.asyncAfter(deadline: .now() + 5, execute: item!)
    }

    deinit {
        item?.cancel()
    }

    func doSomething() { ... }

}

[weak self]ক্যাপচার তালিকার ব্যবহারটি নোট করুন DispatchWorkItem। একটি শক্তিশালী রেফারেন্স চক্র এড়ানোর জন্য এটি প্রয়োজনীয়। এছাড়াও মনে রাখবেন যে এটি একটি প্রাক্প্রটিভ বাতিল করতে পারে না, বরং কাজটি এটি ইতিমধ্যে যদি না করে শুরু করে তবে থামায় starting তবে যদি এটি cancel()কলটির মুখোমুখি হওয়ার সময়ের মধ্যে ইতিমধ্যে শুরু হয়ে যায় , তবে ব্লকটি কার্যকর করা শেষ করবে (যদি আপনি নিজে isCancelledব্লকের ভিতরে যাচাই করেন না)।


5
এটি নির্দেশ করার জন্য ধন্যবাদ, এবং আসলে swift.org/migration-guide এ হাতে হাতে পরিবর্তন আনার প্রয়োজনীয়তার কথা উল্লেখ করেছে।
ম্যাট

1
ওহ দুঃখিত. এখানে অনেক দেরি হয়েছে :)। ভেবেছিল যে সমস্ত জগাখিচুড়ি আসলেই চলবে, তবে ঝাঁপ দাও নি। আইএমও-এর "সহজ" সমাধানটি হ'ল এক-সত্য-সমাধান।
tobiasdm

1
@ রব কীভাবে আমি এটি বাতিল করতে চাই? ধন্যবাদ।
কেমিকোফা ভূত

ঠিক আছে তো আপনি কীভাবে ডায়নামিক ওয়েট যুক্ত করবেন? উদাহরণস্বরূপ, আমার কাছে একটি লেট নম্বর রয়েছে: ফ্লোট = 1.0 1.0 এবং। এখন () + .মিলিসেকেন্ড (সংখ্যা) কাজ করে না। না ডাবল (সংখ্যা)। আমি এটা বুঝতে পারি না।
কেজেল

2
DispatchTimeIntervalপসরা মত .millisecondsপ্রয়োজন Int। তবে যদি কেবল সেকেন্ড যোগ করা হয় তবে আমি Doubleযেমন ব্যবহার করব let n: Double = 1.0; queue.asyncAfter(deadline: .now() + n) { ... }
রব

128

সুইফট 4:

DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) {
   // Code
}

সময়ের জন্য .seconds(Int), .microseconds(Int)এবং .nanoseconds(Int)এটিও ব্যবহৃত হতে পারে।


7
.millisecondsদ্বিগুণ চেয়ে ভাল।
ডনসং

5
খুব সুন্দর. অন্যদের জন্য একটি নোট: আপনি অন্যান্য DispatchTimeIntervalএনাম মানগুলিও ব্যবহার করতে পারেন । case seconds(Int) case milliseconds(Int) case microseconds(Int) case nanoseconds(Int)
রব ম্যাকএচারন

@ রবম্যাকএচারন, ধন্যবাদ যে ভাল পরামর্শটি আমি এটি উত্তরে যুক্ত করছি।
সোভেরিসসন

2
.milliseconds is better than Double. - আমি এটি টি-শার্টে চাই;)।
ক্রিস প্রিন্স

58

আপনি যদি কেবল বিলম্বের কাজটি করতে চান তবে

সুইফট 4 এবং 5

func delay(interval: TimeInterval, closure: @escaping () -> Void) {
     DispatchQueue.main.asyncAfter(deadline: .now() + interval) {
          closure()
     }
}

আপনি এটি ব্যবহার করতে পারেন:

delay(interval: 1) { 
    print("Hi!")
}

DispatchQueue.main.asyncAfter (সময়সীমা:) কাজ করে না। এটি বলে যে এটি তার সুপারক্লাস থেকে কোনও পদ্ধতি ওভারলোড করে না।
ফ্যাব্রিজিও বার্টোলোমুচি

7
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1, execute: closure)সহজ।
ডনসং


5

স্বীকৃত উত্তরের কিছুটা আলাদা স্বাদ।

সুইফট 4

DispatchQueue.main.asyncAfter(deadline: .now() + 0.1 + .milliseconds(500) + 
.microseconds(500) + .nanoseconds(1000)) {
                print("Delayed by 0.1 second + 500 milliseconds + 500 microseconds + 
                      1000 nanoseconds)")
 }

5

সুইফট 4

আপনি ডিসপ্যাচকিউতে একটি এক্সটেনশন তৈরি করতে পারেন এবং ফাংশন বিলম্ব করতে পারেন যা DispatchQueueঅভ্যন্তরীণভাবে asyncAfter ফাংশন ব্যবহার করে

extension DispatchQueue {
   static func delay(_ delay: DispatchTimeInterval, closure: @escaping () -> ()) {
      DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: closure)
   }
}

আর ব্যবহার করুন

DispatchQueue.delay(.milliseconds(10)) {
   print("task to be done")
}

2
এটি কীভাবে @ রকডাসউইফটের উত্তর থেকে আলাদা?
ব্র্যান্ডস্ক্রিপ্ট

যেমনটি আমি উল্লেখ করেছি যে এটি পারফরম্যান্সের পরে asyncAfter এর মোড়ক পরে ফাংশন যা প্যারামিটার হিসাবে বিলম্ব নেয় এবং কেবল
পারফরম্যান্সের

ক্লোজার প্যারামিটারগুলি ডিফল্টরূপে অব্যাহতিপ্রাপ্ত নয়, @ এস্কেপিং ইঙ্গিত দেয় যে একটি ক্লোজার প্যারামিটারটি পালাতে পারে। সম্ভাব্য ক্র্যাশ বাঁচাতে ক্লোজারে পলায়ন পরামিতি যোগ করেছেন
সুহিত পাতিল

3

কল DispatchQueue.main.after(when: DispatchTime, execute: () -> Void)

আমি সুইফট 3 (সম্পাদনা> রূপান্তর> বর্তমান স্যুইফ্ট সিনট্যাক্সে রূপান্তর করতে) এক্সকোড সরঞ্জামগুলি ব্যবহার করার পরামর্শ দিই। এটা আমার জন্য এটি ধরা পড়ে


3

সুইফটে 4.1 এবং এক্সকোড 9.4.1 এ

সহজ উত্তরটি হ'ল ...

//To call function after 5 seconds time
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
//Here call your function
}

3
নিশ্চিত না যে এটি গৃহীত উত্তরের চেয়ে আলাদা কীভাবে?
ব্র্যান্ডস্ক্রিপ্ট


1

উত্তরগুলির কোনও উত্তরই কোনও মূল-মূল থ্রেডে চলছে না, সুতরাং আমার 2 সেন্ট যোগ করুন।

উপর প্রধান কিউ (প্রধান থ্রেড)

let mainQueue = DispatchQueue.main
let deadline = DispatchTime.now() + .seconds(10)
mainQueue.asyncAfter(deadline: deadline) {
    // ...
}

অথবা

DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + .seconds(10)) { 
    // ...
}

উপর বিশ্বব্যাপী কিউ (অ মূল থ্রেড, QOS উপর ভিত্তি করে থাকে)।

let backgroundQueue = DispatchQueue.global()
let deadline = DispatchTime.now() + .milliseconds(100)
backgroundQueue.asyncAfter(deadline: deadline, qos: .background) { 
    // ...
}

অথবা

DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + .milliseconds(100), qos: .background) {
    // ...
}



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