مقدمة في قوائم المهام في Swift
\n\nتطبيقات الهواتف المحمولة وأجهزة الكمبيوتر المكتبية المكتوبة بلغة Swift غالباً ما تنفذ عدة عمليات في وقت واحد: تحميل البيانات من الشبكة، معالجة الصور، تحريك الواجهة. بدون إدارة صحيحة لهذه المهام، قد يتجمد التطبيق أو يبطئ. قوائم المهام هي آلية تسمح بتنظيم تنفيذ الكود في الخلفية دون حظر الخيط الرئيسي (UI).
\n\nيوجد في Swift ثلاثة أساليب رئيسية للعمل مع قوائم المهام:
\n- \n
- Grand Central Dispatch (GCD) — واجهة برمجة تطبيقات منخفضة المستوى لإدارة قوائم المهام. \n
- OperationQueue — تجريد عالي المستوى فوق GCD. \n
- async/await (Swift 5.5+) — بناء جملة غير متزامن حديث. \n
في هذه المقالة، سنشرح كل أسلوب بأمثلة عملية مفهومة حتى للمبتدئين.
\n\n1. Grand Central Dispatch (GCD) — أساس قوائم المهام
\n\nGCD هي مكتبة من Apple تدير مجموعة من الخيوط. يمكنك ببساطة إنشاء قائمة مهام وإرسال المهام إليها. النظام نفسه يقرر على أي خيط سيتم تنفيذ الكود.
\n\nأنواع قوائم المهام في GCD
\n- \n
- Main Queue — تنفذ المهام على الخيط الرئيسي (تحديثات UI فقط). \n
- Global Queues — قوائم مهام خلفية بأولويات مختلفة (userInteractive, userInitiated, utility, background). \n
- Private Queues — قوائم المهام الخاصة بك، والتي يمكن تكوينها إما متسلسلة (serial) أو متزامنة (concurrent). \n
مثال: تحميل البيانات في الخلفية
\nimport UIKit\n\nclass ViewController: UIViewController {\n \n @IBOutlet weak var imageView: UIImageView!\n \n override func viewDidLoad() {\n super.viewDidLoad()\n \n // تشغيل مهمة في قائمة مهام خلفية\n DispatchQueue.global(qos: .userInitiated).async {\n let url = URL(string: "https://example.com/image.jpg")!\n if let data = try? Data(contentsOf: url),\n let image = UIImage(data: data) {\n \n // العودة إلى الخيط الرئيسي لتحديث UI\n DispatchQueue.main.async {\n self.imageView.image = image\n }\n }\n }\n }\n}\n\nقوائم المهام المتسلسلة مقابل المتزامنة
\nقائمة المهام المتسلسلة تنفذ المهام واحدة تلو الأخرى. المتزامنة يمكنها تشغيل عدة مهام في وقت واحد.
\n\n// قائمة مهام متسلسلة\nlet serialQueue = DispatchQueue(label: "com.example.serial")\nserialQueue.async { print("Task 1") }\nserialQueue.async { print("Task 2") }\n// الإخراج: Task 1، ثم Task 2\n\n// قائمة مهام متزامنة\nlet concurrentQueue = DispatchQueue(label: "com.example.concurrent", attributes: .concurrent)\nconcurrentQueue.async { print("Task A") }\nconcurrentQueue.async { print("Task B") }\n// الإخراج: Task A أو Task B (الترتيب غير مضمون)\n\n2. OperationQueue — إدارة التبعيات
\n\nOperationQueue هي غلاف أكثر ملاءمة فوق GCD، يسمح بما يلي:
\n- \n
- تعيين التبعيات بين المهام. \n
- إلغاء تنفيذ المهام. \n
- التحكم في الحد الأقصى لعدد العمليات المتزامنة. \n
إنشاء وتنفيذ العمليات
\nlet operationQueue = OperationQueue()\noperationQueue.maxConcurrentOperationCount = 2 // حد أقصى مهمتين في وقت واحد\n\nlet operation1 = BlockOperation {\n print("العملية 1 قيد التنفيذ")\n Thread.sleep(forTimeInterval: 1)\n}\n\nlet operation2 = BlockOperation {\n print("العملية 2 قيد التنفيذ")\n Thread.sleep(forTimeInterval: 1)\n}\n\n// تعيين تبعية: العملية 2 ستبدأ فقط بعد العملية 1\noperation2.addDependency(operation1)\n\noperationQueue.addOperations([operation1, operation2], waitUntilFinished: false)\n\n