التزامن وتعدد الخيوط في Swift: دليل شامل

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة في التزامن وتعدد الخيوط في Swift



يجب أن تكون تطبيقات الهواتف المحمولة وأجهزة الكمبيوتر المكتبية الحديثة سريعة وسريعة الاستجابة. في التطوير لنظامي iOS وmacOS، تلعب الإدارة الصحيحة للتزامن وتعدد الخيوط دورًا رئيسيًا. يوفر Swift أدوات قوية لتنفيذ المهام بالتوازي، بدءًا من Grand Central Dispatch (GCD) الكلاسيكي وصولاً إلى النموذج الحديث async/await والممثلين (Actors).



في هذه المقالة، سنستعرض جميع الأساليب الأساسية للعمل مع الخيوط في Swift: من المفاهيم الأساسية إلى التقنيات المتقدمة. ستتعلم كيفية تجنب حالات السباق (race conditions) والتوقف التام (deadlocks) والمشاكل الأخرى المميزة للبرمجة متعددة الخيوط.



Grand Central Dispatch (GCD) — كلاسيكيات تعدد الخيوط



Grand Central Dispatch (GCD) هي مكتبة منخفضة المستوى من Apple لإدارة التنفيذ المتوازي للكود. تستخدم قوائم الانتظار (dispatch queues) لتوزيع المهام على الخيوط.



الأنواع الرئيسية لقوائم الانتظار



يوجد في GCD نوعان رئيسيان من قوائم الانتظار:



  • قوائم الانتظار التسلسلية (Serial queues): يتم تنفيذ المهام واحدة تلو الأخرى بترتيب الإضافة. مثالية لمزامنة الوصول إلى الموارد.
  • قوائم الانتظار المتزامنة (Concurrent queues): يمكن تنفيذ المهام في وقت واحد، ولا يتم ضمان ترتيب الإكمال.


مثال على العمل مع GCD



import Foundation

// إنشاء قائمة انتظار تسلسليةlet serialQueue = DispatchQueue(label: "com.example.serial")

// إنشاء قائمة انتظار متزامنةlet concurrentQueue = DispatchQueue(label: "com.example.concurrent", attributes: .concurrent)

// تنفيذ غير متزامنserialQueue.async { print("المهمة 1 تُنفذ في الخلفية")}

// تنفيذ متزامن (يحجب الخيط الحالي)serialQueue.sync { print("المهمة 2 تُنفذ بشكل متزامن")}

// العمل مع الخيط الرئيسيDispatchQueue.main.async { print("تحديث واجهة المستخدم على الخيط الرئيسي")}

// تأخير التنفيذDispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { print("تم التنفيذ بعد ثانيتين")}


Dispatch Group — مزامنة مجموعة من المهام



تسمح Dispatch Group بتتبع إكمال مجموعة من المهام غير المتزامنة وتنفيذ كود بعد انتهائها.



let group = DispatchGroup()let queue = DispatchQueue.global(qos: .background)

for i in 1...5 { queue.async(group: group) { print("المهمة \\(i) بدأت") Thread.sleep(forTimeInterval: Double.random(in: 0.5...2.0)) print("المهمة \\(i) اكتملت") }}

group.notify(queue: DispatchQueue.main) { print("جميع المهام منفذة! نقوم بتحديث واجهة المستخدم.")}


async/await الحديث في Swift 5.5+



بدءًا من Swift 5.5، قدمت Apple نموذجًا جديدًا للتزامن يعتمد على الكلمات المفتاحية async و await. وهذا يجعل الكود غير المتزامن أكثر قابلية للقراءة والفهم.



تعريف الدوال غير المتزامنة



يتم تمييز الدوال غير المتزامنة بالكلمة المفتاحية async، ويتطلب استدعاؤها استخدام await:



import Foundation

// دالة غير متزامنة لتحميل البياناتfunc fetchUserData() async throws -> String { let url = URL(string: "https://api.example.com/user")! let (data, _) = try await URLSession.shared.data(from: url) return String(data: data, encoding: .utf8) ?? "No data"}

// استخدام async/awaitfunc loadUserProfile() async { do { let userData = try await fetchUserData() await MainActor.run { print("بيانات المستخدم: \\(userData)") } } catch { print("خطأ في التحميل: \\(error)") }}

// تشغيل مهمة غير متزامنةTask { await loadUserProfile()}


Async let — التنفيذ المتوازي



تسمح الكلمة المفتاحية async let بتشغيل عدة مهام غير متزامنة بالتوازي:



<                

المدونات

توصيات الكتب