كيفية مشاركة managedObjectContext عند استخدام uitabbarcontroller مع uinavigationcontrollers الداخلية

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

سؤال

لدي سؤال معماري. يستخدم تطبيقي TabbarController مباشرة في نافذة التطبيق. يقوم ApplicationDelegate بإنشاء ManagedObjectContext ، على الرغم من أنه في الواقع لا يحتاج إليه.

كل ViewController في TabbarController هو NavigationViewController. أول وحدة تحكم العرض لكل NavigationController هي وجهات نظراتي المخصصة. كل شيء هو CreateDe مرتبط عبر Builder واجهة.

الآن ، كيف أقوم بتمرير managedObjectContext حول الطريق الصحيح؟ في الواقع ، أحتاج إلى طرق عرضي لتحميل البيانات في أقرب وقت ممكن بحيث عندما يختار المستخدم علامة تبويب أو يتنقل عبر NavigationControllers ، فإن البيانات موجودة بالفعل.

لذلك أسئلتي هي:

  1. كيف أقوم بتمرير السياق بشكل صحيح؟
  2. متى يجب أن أحضر بياناتي ، أي في أي طريقة؟ "viewDidload" أو "ViewDidAppear"؟

شكرا على كل الأفكار!

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

المحلول

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

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

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

نصائح أخرى

لقد واجهت هذه المشكلة نفسها ، سأشارك الحل.

تحتاج أولاً إلى إشارة إلى وحدة التحكم في NAV في شريط علامة التبويب في ملف NIB ، تأكد من توصيله.

IBOutlet UINavigationController *navigationController;

بعد ذلك ، احصل على وحدة التحكم كما هو موصى بها في مستندات الدعم وأرسلها إلى ManagedObjectContext:

SavedTableViewController *saved = (SavedTableViewController *)[navigationController topViewController];
saved.managedObjectContext = self.managedObjectContext;

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

يمكنك الحصول عليها من مندوب التطبيق في أي وقت مثل هذا:

myApp *d = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *managedObjectContext = d.managedObjectContext;

أو الاختلافات أعلاه. بخلاف ذلك ، يمكنك إضافة خاصية إلى جميع مشاريع ViewControllers وتمريرها أو يمكنك إنشاء مفردة ومرجع على مستوى العالم.

سريع

يجب ليس شارك ب NSManagedObjectContext, ، لكنك أستطيع أن أشارك ال NSPersistentStoreCoordinator.

وبالتالي ، يمكنك إنشاء سياق كائن جديد مُدار لكل طريقة عرض ، يشارك كل المتجر نفسه. إنها الطريقة المفضلة ، وتتيح الوصول المتزامن ، متعدد مؤشرات الترابط. في المثال أدناه ، أفترض أن AppDelegate الخاص بك ، *إذا تم إنشاؤه باستخدام إصدار حديث من XCode مع استخدام البيانات الأساسية فحص*، لديه خاصية اسمها persistentStoreCoordinator:

lazy var managedObjectContext:NSManagedObjectContext? = {
    // This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.

    if let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate {
        let coordinator = appDelegate.persistentStoreCoordinator
        var managedObjectContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
        managedObjectContext.persistentStoreCoordinator = coordinator
        return managedObjectContext
    }
    }()
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top