iOS / Swift / قيم Swift وملكية SwiftUI / الدرس 3
حالة SwiftUI والروابط والهوية
عامل الواجهات كأوصاف وامنح الحالة القابلة للتحرير مالكا واحدا يستمر بعمر الهوية المقصودة.
في هذه الصفحة
أهداف الدرس
- تصف قيمة View الواجهة الحالية
- أبق المصدر المحلي للحقيقة خاصا
- يمنح Binding وصولا إلى مالك آخر
تصف قيمة View الواجهة الحالية
تكون View في SwiftUI غالبا بنية يصف body فيها الواجهة حسب المدخلات والحالة. يمكن لـ SwiftUI إعادة إنشاء قيم العرض كثيرا مع حفظ الحالة المدارة لهوية مستقرة. لا تعتبر منشئ البنية أو تقييم body حدثا يحدث مرة واحدة طوال عمر الشاشة. قد يكرر إرسال طلب أو تسجيل مراقب هناك العمل بصورة مفاجئة. أبق body وصفا وضع الأفعال عند حدود الأحداث أو العمر المصممة لها. ليس عدد التقييمات الداخلية مقياسا موثوقا لنية المستخدم أو الحفظ أو الإطارات المعروضة.
أبق المصدر المحلي للحقيقة خاصا
تعلن @State تخزينا تديره SwiftUI لقيمة محلية لهوية عرض. اجعل الحالة المملوكة private كي لا يعامل المستدعي قيمتها الأولية كمدخل عادي يتحكم فيه باستمرار. وإذا وجب أن يملك الأب القيمة، فليستقبل الابن مدخلا للقراءة أو Binding بحسب سلطته. يبدل المقتطف الأول علم كشف محليا ويشتق منه تسمية الزر والتفاصيل. لا يوجد نص ثان مخزن قد يتناقض معه. قد تتطور تفاصيل تنفيذ الحالة بين إصدارات Xcode، لكن الملكية تبقى العقد الأساسي.
import SwiftUI
struct DetailsPanel: View {
@State private var open = false
var body: some View {
VStack {
Button(open ? "Hide" : "Show") { open.toggle() }
if open { Text("Workshop details") }
}
}
}
Initially Show; activation changes the label to Hide and reveals Workshop details.
تملك SwiftUI التخزين لهوية العرض. هذه وحدة View غير منفذة وتتطلب بيئة تطبيق أو معاينة من Apple.
يمنح Binding وصولا إلى مالك آخر
يمثل Binding اتصال قراءة وكتابة بقيمة مملوكة في موضع آخر، ولا ينشئ نسخة مستقلة من مصدر الحقيقة. يستقبل المقتطف الثاني رابط تفضيل ويبدله، ويمرّر الأب إسقاط الحالة ببادئة الدولار. يناسب العقد حين يسمح للابن بتحرير القيمة نفسها. أما الفعل المؤثر المحتاج إلى تحقق فقد يناسبه رد أمر أكثر من رابط غير مقيد. لا تسمح لتحكم زخرفي بتجاوز قواعد المجال عبر كتابة خاصية داخلية مباشرة.
struct FavoriteToggle: View {
@Binding var favorite: Bool
var body: some View {
Toggle("Favorite", isOn: $favorite)
}
}
struct FavoriteHost: View {
@State private var favorite = false
var body: some View { FavoriteToggle(favorite: $favorite) }
}
The child edits the same favorite value owned by FavoriteHost.
يوفر الإسقاط بالدولار رابطا. وتمرير favorite بلا إسقاط يزوّد Bool، وهو نوع مدخل مختلف.
تحدد الهوية عمر الحالة المدارة
قد يؤثر نوع العرض وموضعه البنيوي وهويته الصريحة في حفظ SwiftUI للحالة. وقد يؤدي استبدال فرع بهوية أخرى إلى تصفير المسودات رغم تشابه المظهر. لذلك تعد .id قرار عمر لا زخرفة بلا أثر. لا تستخدم UUID جديدا مع كل body لعنصر يفترض استمراره. وفي الصفوف المتكررة استخدم معرّفات مجال مستقرة لا مواضع المصفوفة. اختبر إعادة ترتيب أو انتقالا شرطيا فعليا مع حقل محرر لكشف فقد الحالة أو انتقالها الخاطئ.
افصل التحرير المحلي عن النماذج المشتركة
المسودة القابلة للإلغاء لا ينبغي بالضرورة أن ترتبط مباشرة بالنموذج المشترك المحفوظ. أنشئ قيمة قابلة للتحرير عن قصد ثم تحقّق واعتمدها عند الحفظ. ويمكن لتفضيل بسيط فوري استخدام رابط مباشر إذا كان ذلك عقد المنتج. ولنماذج مرجعية مشتركة أوسع توفر Observation اعتماديات متتبعة على الأنظمة المدعومة؛ ويجب أن يقرأ العرض الخصائص ذات الصلة. المراقبة آلية إشعار وليست سياسة تفويض أو عمر موارد. اختر الملكية وعزل الممثل صراحة قبل أغلفة الخصائص.
تحقّق من الحالة بالتفاعل وإعادة التشكيل
يحرر فحص مفيد قيمة ثم يسبب تحديثا غير مرتبط للأب ويتأكد من استمرار الحالة المقصودة. ثم يغير الهوية عمدا ويفحص هل التصفير متوقع. اختبر تحكمين يشتركان في رابط واحد ليتسق عرضهما مع المصدر نفسه. وللمسودة القابلة للإلغاء تحقق من حفظ الأصل عند الإلغاء واعتماد الحفظ مرة واحدة عبر الأمر. تكشف هذه الفحوص عيوب ملكية لا تكشفها معاينة ثابتة. تفيد المعاينة في العرض لكنها لا تثبت عقد التنقل والعمر والحفظ كاملا.
الأخطاء الشائعة وإصلاحها
تُصفّر المسودة بعد تحديث غير مرتبط
- لماذا يحدث؟
- تغيرت هوية العرض أو وضعت الملكية في قيمة عابرة.
- كيف تصلحه؟
- احفظ الحالة لدى المالك المستقر وراجع تغير id الصريح.
- كيف تتجنب تكراره؟
- اختبر تحديث الأب أثناء تحرير الحقل.
يحتاج الابن Binding لكنه يستقبل Bool
- لماذا يحدث؟
- مرّر الأب القيمة لا اتصالها المسقط.
- كيف تصلحه؟
- مرّر الرابط المسقط بالدولار عند منح سلطة الكتابة.
- كيف تتجنب تكراره؟
- أظهر الفرق بين المدخل المقروء والقابل للتحرير.
غيّر الإلغاء بيانات محفوظة بالفعل
- لماذا يحدث؟
- ارتبط النموذج مباشرة بالبيانات المعتمدة.
- كيف تصلحه؟
- حرر مسودة مستقلة واعتمدها عبر الحفظ.
- كيف تتجنب تكراره؟
- حدّد الإلغاء قبل نطاق الرابط.
اختبر فهمك
1. هل يحتاج مجموع مشتق من العناصر المختارة إلى State متغيرة مستقلة؟
اعرض الحل المشروح
اشتقه عادة من العناصر المعتمدة كي لا يتباعد. وإذا لزم التخزين المؤقت فاجعل الإبطال لدى المالك نفسه وأدرج الاعتماديات كلها. تخلق النسخ المتغيرة المستقلة عملا للمزامنة لا يحله غلاف الخصائص تلقائيا.
2. لماذا قد تمحو إضافة .id(UUID()) المتكررة مسودة النموذج؟
اعرض الحل المشروح
تقدم هوية صريحة مختلفة في كل تقييم فتطلب معاملة الشجرة كظهور جديد. لا يلزم استمرار الحالة المرتبطة بالهوية القديمة. استخدم هوية مستقرة إلا إذا كان التصفير مقصودا واختبر الانتقال.
أهم ما تعلمته
- تصف قيمة View الواجهة الحالية
- تحقّق من الحالة بالتفاعل وإعادة التشكيل