আমি কীভাবে খেলার মাঠে অ্যাসিঙ্ক্রোনাস কলব্যাক চালাচ্ছি


117

অনেক কোকো এবং কোকো টাচ পদ্ধতিতে অবজেক্ট-সি এবং ব্লকের সুইফটে বন্ধ হিসাবে ব্লক হিসাবে বাস্তবায়ন সম্পন্ন কলব্যাক রয়েছে। যাইহোক, খেলার মাঠে এগুলি চেষ্টা করার সময়, সমাপ্তি কখনই ডাকা হয় না। উদাহরণ স্বরূপ:

// Playground - noun: a place where people can play

import Cocoa
import XCPlayground

let url = NSURL(string: "http://stackoverflow.com")
let request = NSURLRequest(URL: url)

NSURLConnection.sendAsynchronousRequest(request, queue:NSOperationQueue.currentQueue() {
response, maybeData, error in

    // This block never gets called?
    if let data = maybeData {
        let contents = NSString(data:data, encoding:NSUTF8StringEncoding)
        println(contents)
    } else {
        println(error.localizedDescription)
    }
}

আমি আমার প্লেগ্রাউন্ড টাইমলাইনে কনসোল আউটপুট দেখতে পাচ্ছি, তবে printlnআমার সমাপ্তি ব্লকটিকে কখনই ডাকা হয় না ...

উত্তর:


186

আপনি ম্যানুয়ালি একটি রান লুপ চালাতে পারেন (বা, অ্যাসিনক্রোনাস কোডের জন্য যা রান লুপের প্রয়োজন হয় না, অন্যান্য অপেক্ষার পদ্ধতি যেমন প্রেরণে সেম্যাফোরাস ব্যবহার করুন), অ্যাসিঙ্ক্রোনাস কাজের অপেক্ষার জন্য আমরা খেলার মাঠে যে "বিল্ট-ইন" সরবরাহ করি তা হ'ল XCPlaygroundকাঠামো এবং সেট আমদানি করুন XCPlaygroundPage.currentPage.needsIndefiniteExecution = true। যদি এই সম্পত্তিটি সেট করা থাকে, যখন আপনার শীর্ষ স্তরের খেলার মাঠের উত্স শেষ হয়, সেখানে খেলার মাঠ থামানোর পরিবর্তে আমরা মূল রান লুপটি স্পিন করতে থাকব, সুতরাং অ্যাসিঙ্ক্রোনাস কোডটি চালানোর সুযোগ রয়েছে। অবশেষে আমরা খেলার মাঠটি 30 সেকেন্ডের ডিফল্ট সময়সীমা শেষে শেষ করব, তবে আপনি যদি সহকারী সম্পাদকটি খোলেন এবং টাইমলাইন সহকারী দেখান তবে কনফিগার করা যেতে পারে; সময়সীমাটি নিম্ন-ডানদিকে রয়েছে।

উদাহরণস্বরূপ, সুইফ্ট 3 এ ( URLSessionপরিবর্তে ব্যবহার করে NSURLConnection):

import UIKit
import PlaygroundSupport

let url = URL(string: "http://stackoverflow.com")!

URLSession.shared.dataTask(with: url) { data, response, error in
    guard let data = data, error == nil else {
        print(error ?? "Unknown error")
        return
    }

    let contents = String(data: data, encoding: .utf8)
    print(contents!)
}.resume()

PlaygroundPage.current.needsIndefiniteExecution = true

বা সুইফট 2 এ:

import UIKit
import XCPlayground

let url = NSURL(string: "http://stackoverflow.com")
let request = NSURLRequest(URL: url!)

NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.currentQueue()) { response, maybeData, error in
    if let data = maybeData {
        let contents = NSString(data:data, encoding:NSUTF8StringEncoding)
        println(contents)
    } else {
        println(error.localizedDescription)
    }
}

XCPlaygroundPage.currentPage.needsIndefiniteExecution = true

1
এটি সর্বোপরি মূল্যবান, এটি ডাব্লুডাব্লুডিসি 2014 §408 এ আচ্ছাদিত: সুইফ্ট খেলার মাঠ, দ্বিতীয়ার্ধ
ক্রিস

3
DP4 থেকে XCPlaygroundফ্রেমওয়ার্কটি এখন আইওএস প্লেগ্রাউন্ডের জন্যও উপলব্ধ।
ইকুরামিডিয়া

4
আপডেট পদ্ধতি:XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
আর মেনকে

23
আপডেট পদ্ধতি: import PlaygroundSupportএবংPlaygroundPage.current.needsIndefiniteExecution = true
সিম্পলজি

48

এই এপিআইটি এক্সকোড 8 এ আবার পরিবর্তন হয়েছে এবং এটিতে সরানো হয়েছে PlaygroundSupport:

import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

এই পরিবর্তনটি ডাব্লুডাব্লুডিসি 2016 সালে 213 সেশনে উল্লেখ করা হয়েছিল ।


2
কল করতে ভুলবেন না PlaygroundPage.current.finishExecution()
গ্লেন

36

এক্সকোড 7.1 হিসাবে, XCPSetExecutionShouldContinueIndefinitely()অবচিত হয়। এখনই করার সঠিক উপায় হ'ল প্রথমে বর্তমান পৃষ্ঠার সম্পত্তি হিসাবে অনির্দিষ্টকালের কার্যকরকরণের অনুরোধ করা:

import XCPlayground

XCPlaygroundPage.currentPage.needsIndefiniteExecution = true

… তারপরে নির্বাহ শেষ হয়ে গেলে নির্দেশ করুন:

XCPlaygroundPage.currentPage.finishExecution()

উদাহরণ স্বরূপ:

import Foundation
import XCPlayground

XCPlaygroundPage.currentPage.needsIndefiniteExecution = true

NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: "http://stackoverflow.com")!) {
    result in
    print("Got result: \(result)")
    XCPlaygroundPage.currentPage.finishExecution()
}.resume()

16

কলব্যাকগুলি না ডাকার কারণটি হ'ল রানলুপ প্লেগ্রাউন্ডে চলছে না (বা সেই বিষয়ে REPL মোডে)।

কিছুটা ঝাঁকুনির, তবে কার্যকর, কলব্যাকগুলি পরিচালনা করার উপায় একটি পতাকা সহকারে এবং নিজেই রান-লুপটিতে পুনরুক্তি:

// Playground - noun: a place where people can play

import Cocoa
import XCPlayground

let url = NSURL(string: "http://stackoverflow.com")
let request = NSURLRequest(URL: url)

var waiting = true

NSURLConnection.sendAsynchronousRequest(request, queue:NSOperationQueue.currentQueue() {
response, maybeData, error in
    waiting = false
    if let data = maybeData {
        let contents = NSString(data:data, encoding:NSUTF8StringEncoding)
        println(contents)
    } else {
        println(error.localizedDescription)
    }
}

while(waiting) {
    NSRunLoop.currentRunLoop().runMode(NSDefaultRunLoopMode, beforeDate: NSDate())
    usleep(10)
}

ইউনিট টেস্টগুলিতে এই প্যাটার্নটি প্রায়শই ব্যবহৃত হয় যার জন্য অ্যাসিঙ্ক কলব্যাকগুলি পরীক্ষা করা দরকার, উদাহরণস্বরূপ: ইউনিট পরীক্ষার জন্য প্যাটার্ন অ্যাসিঙ্ক ক্যু যা সম্পূর্ণরূপে মূল সারিকে কল করে


8

এক্সকোড 8, সুইফট 3 এবং আইওএস 10 এর মতো নতুন এপিআইগুলি হ'ল,

// import the module
import PlaygroundSupport
// write this at the beginning
PlaygroundPage.current.needsIndefiniteExecution = true
// To finish execution
PlaygroundPage.current.finishExecution()

5

সুইফট 4, এক্সকোড 9.0

import Foundation
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

let url = URL(string: "https://jsonplaceholder.typicode.com/posts/1")!

let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
    guard error == nil else {
        print(error?.localizedDescription ?? "")
        return
    }

    if let data = data, let contents = String(data: data, encoding: String.Encoding.utf8) {
        print(contents)
    }
}
task.resume()

3

সুইফট 3, এক্সকোড 8, আইওএস 10

মন্তব্য:

সংকলককে বলুন যে খেলার মাঠের ফাইলটির জন্য "অনির্দিষ্টকালের কার্যকরকরণ" প্রয়োজন

PlaygroundSupport.current.completeExecution()আপনার সমাপ্তি হ্যান্ডলারের মধ্যে একটি কলের মাধ্যমে ম্যানুয়ালি সম্পাদনা শেষ করুন ।

আপনি ক্যাশে ডিরেক্টরিটি নিয়ে সমস্যায় পড়তে পারেন এবং এটি সমাধান করার জন্য আপনাকে ইউআইকেচে.সারেড সিঙ্গলটন ম্যানুয়ালি পুনরায় ইনস্ট্যান্ট করতে হবে।

উদাহরণ:

import UIKit
import Foundation
import PlaygroundSupport

// resolve path errors
URLCache.shared = URLCache(memoryCapacity: 0, diskCapacity: 0, diskPath: nil)

// identify that the current page requires "indefinite execution"
PlaygroundPage.current.needsIndefiniteExecution = true

// encapsulate execution completion
func completeExecution() {
    PlaygroundPage.current.finishExecution()
}

let url = URL(string: "http://i.imgur.com/aWkpX3W.png")

let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
    var image = UIImage(data: data!)

    // complete execution
    completeExecution()
}

task.resume()

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