যেমনটি এখানে উল্লেখ করা হয়েছে এবং অন্যান্য এসও প্রশ্নের উত্তর হিসাবে উল্লেখ করা হয়েছে, আপনি beginBackgroundTask
কেবল তখনই ব্যবহার করতে চাইবেন না যখন আপনার অ্যাপটি ব্যাকগ্রাউন্ডে যাবে; বিপরীতে, আপনার যে কোনও সময় গ্রহণকারী ক্রিয়াকলাপের জন্য একটি ব্যাকগ্রাউন্ড টাস্ক ব্যবহার করা উচিত যার অ্যাপ্লিকেশন ব্যাকগ্রাউন্ডে চলে না গেলেও আপনি এটি নিশ্চিত করতে চান completion
সুতরাং আপনার কোডটি একই বয়লারপ্লেট কোডটির পুনরাবৃত্তিগুলি কল করার জন্য beginBackgroundTask
এবং endBackgroundTask
সুসংগতভাবে শেষ হতে পারে। এই পুনরাবৃত্তি রোধ করতে, বয়লারপ্লেটটিকে কিছু একক এনপ্যাপুলেটেড সত্তায় প্যাকেজ করতে চান তা অবশ্যই যুক্তিসঙ্গত।
আমি এটি করার জন্য কিছু বিদ্যমান উত্তর পছন্দ করি তবে আমার মনে হয় একটি অপারেশন সাবক্লাস ব্যবহার করা সবচেয়ে ভাল উপায়:
আপনি যে কোনও অপারেশনকিউতে অপারেশনটিকে সারিবদ্ধ করতে পারেন এবং উপযুক্ত দেখায় সেই সারিটি পরিচালনা করতে পারেন। উদাহরণস্বরূপ, আপনি কাতারে বিদ্যমান যে কোনও ক্রিয়াকলাপ অসময়ে বাতিল করতে পারেন।
যদি আপনার একাধিক কাজ করতে হয় তবে আপনি একাধিক ব্যাকগ্রাউন্ড টাস্ক অপারেশনগুলি চেইন করতে পারেন। অপারেশন নির্ভরতা সমর্থন করে।
অপারেশন সারি একটি পটভূমি সারি হতে পারে (এবং হওয়া উচিত); সুতরাং, আপনার টাস্কের মধ্যে অ্যাসিনক্রোনাস কোড সম্পাদন করার বিষয়ে কোনও চিন্তা করার দরকার নেই, কারণ অপারেশন হ'ল অ্যাসিনক্রোনাস কোড। (প্রকৃতপক্ষে, অপারেশনের অভ্যন্তরে অ্যাসিক্রোনাস কোডের অন্য স্তরটি কার্যকর করার কোনও অর্থ হয় না , কারণ কোডটি শুরু হওয়ার আগেই অপারেশন শেষ হয়ে যায়। যদি আপনাকে এটি করার দরকার হয় তবে আপনি অন্য অপারেশনটি ব্যবহার করবেন।)
এখানে একটি সম্ভাব্য অপারেশন সাবক্লাস রয়েছে:
class BackgroundTaskOperation: Operation {
var whatToDo : (() -> ())?
var cleanup : (() -> ())?
override func main() {
guard !self.isCancelled else { return }
guard let whatToDo = self.whatToDo else { return }
var bti : UIBackgroundTaskIdentifier = .invalid
bti = UIApplication.shared.beginBackgroundTask {
self.cleanup?()
self.cancel()
UIApplication.shared.endBackgroundTask(bti) // cancellation
}
guard bti != .invalid else { return }
whatToDo()
guard !self.isCancelled else { return }
UIApplication.shared.endBackgroundTask(bti) // completion
}
}
এটি কীভাবে ব্যবহার করবেন তা স্পষ্ট হওয়া উচিত, তবে এটি যদি না হয় তবে কল্পনা করুন যে আমাদের একটি বিশ্বব্যাপী অপারেশনকিউ রয়েছে:
let backgroundTaskQueue : OperationQueue = {
let q = OperationQueue()
q.maxConcurrentOperationCount = 1
return q
}()
সুতরাং কোডের একটি সাধারণ সময়সাপেক্ষ ব্যাচের জন্য আমরা বলব:
let task = BackgroundTaskOperation()
task.whatToDo = {
// do something here
}
backgroundTaskQueue.addOperation(task)
আপনার যদি সময় ব্যয়কারী কোডের ব্যাচটি পর্যায়গুলিতে বিভক্ত করা যায় তবে আপনার কাজটি বাতিল হয়ে থাকলে আপনি খুব তাড়াতাড়ি মাথা নত করতে চাইতে পারেন। সেক্ষেত্রে বন্ধ হওয়া থেকে অকাল সময়ের আগে ফিরে আসুন। নোট করুন যে বন্ধের মধ্যে থেকেই আপনার কাজের উল্লেখটি দুর্বল হওয়া দরকার বা আপনি একটি ধরে রাখার চক্র পাবেন। এখানে একটি কৃত্রিম চিত্রণ:
let task = BackgroundTaskOperation()
task.whatToDo = { [weak task] in
guard let task = task else {return}
for i in 1...10000 {
guard !task.isCancelled else {return}
for j in 1...150000 {
let k = i*j
}
}
}
backgroundTaskQueue.addOperation(task)
যদি ব্যাকগ্রাউন্ড টাস্কটি অকাল সময়ের আগে নিজেই বাতিল হয়ে যায় সে ক্ষেত্রে আপনার পরিষ্কার-পরিচ্ছন্নতার ক্ষেত্রে আমি একটি .চ্ছিক cleanup
হ্যান্ডলারের সম্পত্তি সরবরাহ করেছি (পূর্ববর্তী উদাহরণগুলিতে ব্যবহৃত হয় না)। অন্যান্য কিছু উত্তর এটি সহ না জন্য সমালোচিত হয়েছিল।