iOS / Swift / التزامن وحدود البيانات / الدرس 10
إعادة دخول الممثل وحداثة النتائج
احم الترتيب الدلالي عبر التعليق حتى عندما يمنع عزل الممثل الوصول غير المتزامن للذاكرة.
في هذه الصفحة
أهداف الدرس
- أمان سباق البيانات ليس سياسة أحدث نتيجة
- التقط هوية الطلب قبل التعليق
- لا تسمح لخطأ قديم باستبدال نجاح حالي
أمان سباق البيانات ليس سياسة أحدث نتيجة
تحمي الممثلّات حالتها من الوصول غير المتزامن، لكن يمكن لدالتها التعليق أثناء انتظار عملية أخرى، فتسمح لرسالة أخرى بتغيير الحالة. عند المتابعة قد تبطل افتراضات ما قبل await. قد ينتهي البحث الأول أخيرا ويستبدل الأحدث ما لم يحدد النموذج الترتيب. هذا سباق دلالي ولا يلزم أن يكون سباق ذاكرة. حدّد العملية صاحبة حق النشر حاليا وأعد فحص الملكية بعد التعليق بدلا من الاكتفاء بتعليق الممثل.
التقط هوية الطلب قبل التعليق
المقتطف الأول نموذج بحث على الممثل الرئيسي بتذكرة لكل محاولة. ويُعلن المستودع معزولا على الممثل نفسه لتوضيح الحد التعليمي وتجنب افتراض نقل غير محدد. يمكن تصميم ممثل مستقل أو نقل Sendable مع توثيق الحد. يلتقط كل تحميل التذكرة قبل الانتظار ويقارنها قبل نشر النجاح أو الفشل. حفظ النتائج السابقة عند فشل حالي سياسة تحديث مقصودة. ولا يدّعي النموذج الإلغاء أو تفويض الخادم.
@MainActor protocol SearchRepository {
func search(_ query: String) async throws -> [String]
}
@MainActor final class SearchModel {
private let repository: any SearchRepository
private var ticket = 0
private(set) var results: [String] = []
private(set) var failed = false
init(repository: any SearchRepository) { self.repository = repository }
func load(_ query: String) async {
ticket += 1
let mine = ticket
do {
let next = try await repository.search(query)
guard mine == ticket else { return }
results = next; failed = false
} catch {
guard mine == ticket else { return }
failed = true
}
}
}
Only the most recently started load can replace results or the failure flag.
ليس النموذج تنفيذا مراقبا للواجهة عمدا؛ بل يعزل سياسة النشر ويوضحها باعتماد محقون.
لا تسمح لخطأ قديم باستبدال نجاح حالي
يحمي إصلاح جزئي شائع النتيجة الناجحة فقط. فإذا رمى الطلب الأقدم خطأ لاحقا فقد يحول catch غير المحمي شاشة ناجحة إلى خطأ قديم. طبّق الهوية على كل نشر، بما فيه التنظيف الذي يغير الانشغال. وإذا شاركت عمليات علما واحدا فقد يمحوه اكتمال قديم بينما ما زالت الجديدة نشطة. نمذج مالك العمل المعلق أو اشتق الانتظار من العملية الحالية بدلا من مساواة سلطة كل الاكتمالات.
أدرج ملكية الجلسة حين تتغير الحسابات
يعبر المقتطف الثاني عن بوابة نشر لجيلي الطلب والجلسة معا. زد جيل الجلسة عند تغير ملكية الحساب وأبطل المخازن الخاصة بالنطاق نفسه. قد تبقى الشاشة عبر الخروج والدخول، فلا يثبت وجودها انتماء النتيجة للمستخدم الحالي. احفظ معرّفات آمنة للتشخيص دون رموز سرية أو استعلامات شخصية. تتحكم البوابة بالنشر المحلي فقط؛ وتفحص الخدمة المعتمدة التوثيق والصلاحية عند تقييم الأمر.
struct PublicationIdentity: Equatable, Sendable {
let session: Int
let request: Int
}
func mayPublish(started: PublicationIdentity, current: PublicationIdentity) -> Bool {
started == current
}
let old = PublicationIdentity(session: 1, request: 7)
let current = PublicationIdentity(session: 2, request: 7)
print(mayPublish(started: old, current: current))
false
يمثل رقم الطلب نفسه في جلسة جديدة مالكا مختلفا. لا تلغي المقارنة العمل ولا تفرض صلاحية بعيدة.
يكمل الإلغاء وتأخير البدء فحوص الهوية
قد يقلل تأخير البدء عدد عمليات البحث أثناء الكتابة، وقد يقلل الإلغاء العمل إذا تعاونت العملية. لا يثبت أي منهما وحده استحالة وصول اكتمال قديم للنموذج. ربما جُدول رد النداء أو اكتملت الخدمة قبل ملاحظة الإلغاء. أبق فحص الهوية عند الاعتماد حتى مع تحسين العمل قبله. ولا تطبق أحدث بحث عميانا على المعاملات؛ فقد غيّر حفظ أقدم الخادم ويحتاج إلى تسوية لا إهمال صامت.
استخدم اختبارات ترتيب اكتمال محددة
وفّر مستودعا مزيفا بنتائج معلقة يتحكم بكل منها مستقلا. ابدأ A ثم B وأكمل B ثم A وافحص بقاء B معتمدة. كرر بفشل A بعد نجاح B وتغير الجلسة قبل اكتمال A. وافحص عجز القديم عن محو مؤشر انتظار العملية الحالية. استخدم استمرارات صريحة أو بديلا محدودا لا نوما اعتباطيا. واذكر نمط اللغة وتعليقات الممثل في التقرير المنفذ. لم يُنفذ اختبار تشغيل لتزامن Swift أثناء التأليف.
الأخطاء الشائعة وإصلاحها
تستبدل البيانات القديمة أحدث استعلام
- لماذا يحدث؟
- اعتمد النموذج على العزل دون هوية نشر.
- كيف تصلحه؟
- قارن هوية الطلب بعد await وقبل الاعتماد.
- كيف تتجنب تكراره؟
- اختبر ترتيب اكتمال معكوسا.
يمحو فشل قديم شاشة ناجحة
- لماذا يحدث؟
- فحص فرع النجاح وحده الحداثة.
- كيف تصلحه؟
- طبّق البوابة على الأخطاء وتنظيف الانتظار أيضا.
- كيف تتجنب تكراره؟
- أكمل الطلبات القديمة بنجاح وفشل.
يكشف تبديل الحساب محتوى الجلسة السابقة
- لماذا يحدث؟
- أغفلت الهوية ملكية الحساب ونطاق المخزن.
- كيف تصلحه؟
- أبطل عمل الجلسة وقارن جيلها.
- كيف تتجنب تكراره؟
- اختبر تبديل الدخول أثناء عمل معلق.
اختبر فهمك
1. هل قد تحوي دالة تحميل على الممثل الرئيسي عيب نتيجة متقادمة؟
اعرض الحل المشروح
نعم. قد تعلق عند await بينما يبدأ فعل آخر تحميلا أحدث على الممثل نفسه. يمنع العزل الوصول غير المنظم لا خطأ الترتيب الدلالي. التقط الهوية قبل التعليق وأعد فحصها قبل كل نشر.
2. لماذا لا يضبط الاكتمال القديم busy إلى false دون شرط؟
اعرض الحل المشروح
قد تظل عملية أحدث نشطة. يمكّن محو العلم أزرارا مكررة أو يعلن اكتمالا كاذبا. اربط المؤشر بهوية العملية الحالية، ولا ينهي انتقال الانتظار إلا مالكها.
أهم ما تعلمته
- أمان سباق البيانات ليس سياسة أحدث نتيجة
- استخدم اختبارات ترتيب اكتمال محددة