Back home

سلسلة SwiftUI 08|المزالق الشائعة لقائمة SwiftUI: التحديث والحذف والقفز والأداء

تكمن الصعوبة الحقيقية في القائمة في أنه بمجرد تشابك هوية البيانات وتحديثات الحالة وسلوكيات التفاعل، فمن السهل التسبب في حدوث مشكلات معًا.

List هو أحد عناصر التحكم في SwiftUI التي تعتبر الأسهل في “أن تبدو سهلة الكتابة” وأيضًا الأسهل في الوقوع في المشاكل في الأعمال الحقيقية.

لأن العديد من الأمثلة البسيطة تعمل بشكل جيد:

  • يمكن عرض البيانات بمجرد طرحها
  • يمكن أيضًا الوصول إلى التحديث المنسدل
  • يبدو أن الحذف والقفز والتقسيم يتمتع بقدرات جاهزة

ولكن بمجرد أن يبدأ في الظهور في المشروع:

  • ترقيم الصفحات
  • بحث
  • ربط الحالة بعد الحذف
  • انتقل إلى التفاصيل والعودة
  • تحميل الصورة

سيتم الكشف تدريجياً عن مشكلة List.

1. السبب الجذري للعديد من مشكلات القائمة هو عدم التفكير بوضوح في “هوية البيانات”.

ترتبط العديد من سلوكيات SwiftUI بقوة بالهوية. إذا كانت بيانات القائمة “تبدو كما هي” ولكن الهوية غير مستقرة، فسوف تظهر بسهولة لاحقًا:

  • يرتد عند التحديث
  • رسوم متحركة غريبة عند الحذف
  • موضع التمرير غير طبيعي بعد العودة إلى القائمة
  • يتم تحديث محتوى صف معين بشكل غير صحيح

لذا فإن الشيء الأساسي والأكثر استخفافًا في List هو:

  • هل هوية كل عنصر مستقرة؟
  • هل لا تزال هذه الهوية جديرة بالثقة عند التحديث والترحيل والبحث؟

العديد من قوائم “الأخطاء الميتافيزيقية”، السبب الجذري النهائي موجود هنا.

2. غالبًا ما يؤدي التحديث والترحيل إلى إفساد حالة القائمة.

نظرًا لأن التحديث والترحيل يعدلان بشكل أساسي “مجموعة القائمة الحالية”، فإن تغييرات المجموعة ستؤثر بشكل مباشر على:

  • علاقة إعادة استخدام الخلايا
  • موقف التمرير
  • حالة التحميل الحالية
  • التبديل بين الحالة الفارغة وحالة المحتوى

إذا لم يتم توضيح هذه العلاقات فمن السهل:

  • ستومض القائمة عند سحبها للأسفل للتحديث.
  • ترقيم الصفحات مرة أخرى وإعادة حساب القائمة بأكملها
  • النتائج القديمة تحل محل المحتوى الجديد

لذا فإن الصعوبة الحقيقية في List غالبًا ما تكون:

  • ما هي الحالات التي يجب الاحتفاظ بها عند التحديث؟
  • ما هي الحالات التي يجب إضافتها عند الترحيل؟ -ما إذا كان سيكون هناك تعارضات متزامنة بين الطلبات من نفس النوع

3. عمليات الحذف ليست في الغالب بسيطة مثل “حذف عنصر”

على السطح، يؤدي الحذف فقط إلى إزالة عنصر من المصفوفة. لكن في القوائم الحقيقية، غالبًا ما يؤثر الحذف على هذه الأشياء في نفس الوقت:

  • مجموعة العرض الحالية
  • حكم الدولة الفارغة
  • الحالة المختارة
  • حالة القفز
  • حالة المزامنة الخلفية

إذا قمت فقط “بالحذف أولاً ثم التحدث”، فمن السهل القيام بما يلي:

  • تمت عملية الحذف بنجاح، لكن صفحة التفاصيل ما زالت تشير إلى الكائن القديم
  • عند فشل الحذف، تكون القائمة وحالة الخادم غير متناسقتين
  • الرسوم المتحركة جيدة، ولكن منطق التراجع عن مصدر البيانات مربك

وهذا يوضح أن الصعوبة الحقيقية في الحذف هي:

  • من يملك مصدر البيانات؟
  • هل الحذف تحديث متفائل أم انتظار تأكيد من الخادم؟
  • كيفية إغلاق حالة التنقل بعد الحذف؟

4. من السهل أن يتشابك القفز مع القائمة ويسبب المشاكل.

من الشائع اعتبار القوائم والانتقالات وظائف مستقلة، ولكن في المشاريع الحقيقية تكون مرتبطة بشكل وثيق جدًا.

تشمل الأسئلة النموذجية ما يلي:

  • حذف العنصر الحالي بعد الضغط على التفاصيل، والعودة إلى حالة القائمة غير صحيحة.
  • بعد تحديث القائمة، سيصبح المسار الأصلي المحدد غير صالح.
  • تنتقل نتائج البحث إلى التفاصيل ثم تعود، ويتم إعادة ضبط حالة القائمة.

طبيعة هذه المشاكل عادة ما تكون:

  • قائمة حالة البيانات
  • حالة العنصر المحدد
  • حالة مسار الملاحة

لا يتم التعامل معها على أنها نفس مجموعة المشاكل.

5. من السهل أن تتفجّر مشاكل الأداء في القائمة بشكل خاص

لأن القائمة تضخم العديد من المشاكل الصغيرة.

على سبيل المثال:

  • التسلسل الهرمي لعرض العنصر عميق جدًا
  • تحميل الصور وفك تشفيرها بعد فوات الأوان
  • يتم تحويل النصوص والبيانات في مرحلة العرض
  • حجم التحديث كبير جدًا

قد تكون هذه التكاليف محتملة على الصفحات العادية، ولكن في سيناريوهات التمرير عالية التردد مثل List، يمكن أن تؤدي بسهولة إلى انخفاض الإطار والوميض.

لذلك هناك العديد من مشكلات الأداء في List، وهو حساس بشكل خاص لهوية البيانات ونطاق التحديث وتوقيت العرض.

6. فكرة أكثر استقرارًا: تعامل أولاً مع القائمة على أنها “إسقاط حالة” بدلاً من “حاوية للبيانات”

من المواقف الشائعة أنه عند كتابة قائمة، يكون الوضع الافتراضي في الاعتبار هو:

  • لدي مجموعة من البيانات
  • ضع في القائمة

الفكرة الأكثر استقرارًا في المشاريع الحقيقية هي:

  • ما هي حالة الصفحة الحالية؟
  • ما هي مجموعة عناصر القائمة التي ينبغي إسقاط مجموعة الحالات هذه عليها؟
  • عناصر القائمة التي لها هويات مستقرة
  • ما هي إجراءات المستخدم التي ستغير هذه المجموعة من الحالات

بمجرد أن تفكر في List باعتباره إسقاطًا للحالة وليس حاوية بسيطة، تبدأ العديد من الأسئلة في الوضوح:

  • إعطاء الأولوية للهوية
  • لا يمكن عرض الحذف والتحديث والترحيل بشكل منفصل
  • ينبغي أيضًا النظر في حالة القفز معًا

7. الاستنتاج: الصعوبة الحقيقية في القائمة هي أن “الهوية، والحالة، والتفاعل” يمكن أن تتشابك بسهولة معًا.

ولكي أختصر الأمر أقول:

List في SwiftUI الجزء الصعب حقًا هو أنه بمجرد تشابك تفاعلات هوية البيانات وحالة الصفحة والحذف/التحديث/الانتقال، إذا لم يتم إنشاء أي حدود، فسيتم كشف المشكلات معًا.

لذلك، إذا كنت تريد استخدام List بثبات، فالمفتاح هو أولاً:

  • هوية السلعة
  • حالة القائمة
  • تدفق الحالة بعد التفاعل

تصويب هذه الأشياء الثلاثة.

FAQ

What to read next

Related

Continue reading