عرض لم يظهر:تم استدعاؤه مرتين على وحدة تحكم العرض المشروط المقدمة أثناء بدء التشغيل

StackOverflow https://stackoverflow.com/questions/619269

سؤال

دقة: أثناء محاولتي إعادة إنشاء هذا الخطأ في مشروع جديد لإرساله إلى Apple، اكتشفت أنه خاص بنظام التشغيل iPhone OS 2.1، وأن التحويل البرمجي للإصدار 2.2 يعمل على حل المشكلة.ستيفن، شكرا لمساعدتكم.سأقبل إجابتك لأنها كانت ستنجح إذا كان الخطأ لا يزال موجودًا أو لم أكن على استعداد للتجميع للإصدار 2.2.


لدي تطبيق يقوم بتغيير مخطط قاعدة البيانات بشكل جذري بطريقة تتطلب مني تحويل السجلات ذات النمط القديم إلى سجلات ذات نمط جديد في التعليمات البرمجية.نظرًا لأن المستخدمين قد يقومون بتخزين الكثير من البيانات في هذا التطبيق، فأنا أحاول عرض وحدة تحكم عرض مشروطة مع شريط تقدم أثناء نقل البيانات (على سبيل المثال:كأول شيء يراه المستخدم).وحدة تحكم العرض هذه viewDidAppear: يبدأ معاملة قاعدة البيانات ثم يبدأ مؤشر ترابط في الخلفية للقيام بالنقل الفعلي، والذي يستخدم أحيانًا performSelectorInMainThread:withObject:waitUntilDone: لإخبار مؤشر الترابط الأمامي بتحديث شريط التقدم.

المشكلة هي، viewDidAppear: يتم استدعاؤه مرتين.لقد لاحظت هذا لأن خطوة "بدء المعاملة" تفشل مع ظهور رسالة "قاعدة البيانات مشغولة"، ولكن تعيين نقطة توقف يكشف أنه يتم استدعاؤها بالفعل مرتين - مرة واحدة -[UIViewController viewDidMoveToWindow:shouldAppearOrDisappear:], ، ومرة ​​أخرى بواسطة -[UIViewController modalPresentTransitionDidComplete].يبدو أن هذه الأسماء هي أساليب UIViewController خاصة، لذلك أعتقد أن هذا إما خطأ في إطار العمل، أو أنني أفعل شيئًا لا يتوقع مني UIKit أن أفعله.

مقتطفان من التعليمات البرمجية ذات الصلة (تم تلخيص بعض التعليمات البرمجية غير ذات الصلة):

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    (register some default settings in NSUserDefaults)

    // doing this early because trying to present a modal view controller 
    // before the view controller is visible seems to break it
    [window addSubview:[self.navigationController view]];

    // this is the method that may present the modal view
    [self.databaseController loadDatabaseWithViewController:self.navigationController];

    if(!self.databaseController.willUpgrade) {
        [self restoreNavigationControllerState];
    }
}

ومن فئة DatabaseController الخاصة بي:

- (void)loadDatabaseWithViewController:(UIViewController*)viewController {
    (open the new database)

    (compute the path the old database would live at if it existed)

    if([[NSFileManager defaultManager] fileExistsAtPath:oldDBPath]) {
        (open the old database)

        [viewController presentModalViewController:self animated:NO];
    }
}

إذن، هل هناك شيء أفسدته هنا، أم يجب أن أقوم بتقديم تقرير خطأ إلى شركة Apple؟

هل كانت مفيدة؟

المحلول

لقد رأيت هذا في تطبيقي أيضًا.لم أتأكد مطلقًا من ذلك تمامًا، لكن أعتقد أن هذا ما يحدث:

  1. تحميل عرض الجذر
  2. تحميل عرض مشروط
  3. يظهر نظام التشغيل الذي يرسل العرض إشعارًا للعرض في الخطوة 1
  4. ال حاضِر وحدة تحكم العرض، والتي في هذه الحالة تكون فئة DatabaseController الخاصة بك، تلتقطها
  5. يرسل نظام التشغيل إشعارًا بالعرض المشروط للعرض المشروط
  6. تحصل وحدة التحكم في العرض الحالي على الإشعار.في هذه الحالة، هي نفس وحدة التحكم تمامًا مثل المرة السابقة

في حالتي قمت للتو بإعادة ضبط ما حدث في المكالمة الأولى لـ viewDidAppear:.

في حالتك يتبادر إلى ذهنك خياران:متغير ثابت لتتبع ما إذا كنت قد بدأت الترقية بالفعل؛أو أنظر إلى UIView* تم تمرير المعلمة قبل البدء.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top