थोड़ी देर के लिए यह सोचने के बाद मैं एक समाधान के साथ आया हूं, मैं खुश हूं। exit(0)
विकल्प के साथ विचार करने की एक बात यह है कि यदि डिवाइस को डिवाइस अनलॉक करने में कुछ समय लगता है, तो ऐप लगातार लोड हो रहा है, छोड़ रहा है, और पुनः लोड हो सकता है। जबकि यदि आप ऐप को बहुत कुछ करने से रोकते हैं, तो शायद इसे केवल एक बार लोड करना होगा, और अधिकतर अधिक कुशल होगा। इसलिए मैंने अपना विकल्प 3 आजमाने का फैसला किया और यह वास्तव में कितना गन्दा था। यह मैंने सोचा जितना आसान हो गया।
सबसे पहले मैं अपने ऐप प्रतिनिधि के लिए एक BOOL setupComplete
संपत्ति गयी। यह मुझे यह देखने का एक आसान तरीका देता है कि ऐप को विभिन्न बिंदुओं पर पूरी तरह से लॉन्च किया गया था या नहीं। तब application:didFinishLaunchingWithOptions:
में मैं प्रबंधित वस्तु संदर्भ प्रारंभ करने का प्रयास है, तो कुछ इस तरह करते हैं:
NSManagedObjectContext *moc = [self managedObjectContext];
if (moc) {
self.setupComplete = YES;
[self setupWithManagedObjectContext:moc];
} else {
UIApplication *app = [UIApplication sharedApplication];
if ([app applicationState] == UIApplicationStateBackground && ![app isProtectedDataAvailable]) {
[app beginIgnoringInteractionEvents];
} else [self presentErrorWithTitle:@"There was an error opening the database."];
}
setupWithManagedObjectContext:
सिर्फ इतना है कि सेट अप करना पूर्ण एक कस्टम विधि है। मुझे यकीन नहीं है कि beginIgnoringInteractionEvents
आवश्यक है, लेकिन मैंने इसे सुरक्षित पक्ष में जोड़ा। इस तरह जब ऐप को सामने लाया जाता है, तो मैं सुनिश्चित कर सकता हूं कि सेटअप पूर्ण होने तक इंटरफ़ेस जमे हुए है। यदि कोई उत्सुक उपयोगकर्ता चिंतित रूप से टैप कर रहा है तो यह एक दुर्घटना से बच सकता है।
फिर applicationProtectedDataDidBecomeAvailable:
में मैं कुछ इस तरह कहते हैं:
if (!self.setupComplete) {
NSManagedObjectContext *moc = [self managedObjectContext];
if (moc) {
self.setupComplete = YES;
[self setupWithManagedObjectContext:moc];
UIApplication *app = [UIApplication sharedApplication];
if ([app isIgnoringInteractionEvents]) [app endIgnoringInteractionEvents];
} else [self presentErrorWithTitle:@"There was an error opening the database."];
}
सेटअप खत्म और इंटरफ़ेस को पुन: सक्षम है। यह सबसे अधिक काम है, लेकिन आपको यह सुनिश्चित करने के लिए अपने अन्य कोड को भी जांचना होगा कि कोर डेटा पर निर्भर कुछ भी आपके लगातार स्टोर से पहले कॉल हो रहा है। एक बात यह देखने के लिए है कि applicationWillEnterForeground
और applicationDidBecomeActive
applicationProtectedDataDidBecomeAvailable
से पहले कॉल किया जा सकता है यदि उपयोगकर्ता इस पृष्ठभूमि स्थिति से ऐप लॉन्च करता है। इसलिए विभिन्न स्थानों पर मैंने if (self.setupComplete) { … }
को यह सुनिश्चित करने के लिए जोड़ा है कि यह तैयार होने से पहले कुछ भी नहीं चलता है। मेरे पास कुछ स्थानों पर भी था जहां डेटाबेस लोड होने के बाद मुझे इंटरफ़ेस रीफ्रेश करने की आवश्यकता थी।
आदेश में (आंशिक रूप से) परीक्षा इस के आसपास ड्राइविंग का एक बहुत बिना, मैं अस्थायी रूप से संशोधित application:didFinishLaunchingWithOptions:
डेटाबेस की स्थापना नहीं करने के लिए:
NSManagedObjectContext *moc = nil; // [self managedObjectContext];
if (moc) {
self.setupComplete = YES;
[self setupWithManagedObjectContext:moc];
} else {
UIApplication *app = [UIApplication sharedApplication];
// if ([app applicationState] == UIApplicationStateBackground && ![app isProtectedDataAvailable]) {
[app beginIgnoringInteractionEvents];
// } else [self presentErrorWithTitle:@"There was an error opening the database."];
}
तब मैं अपने कोड applicationProtectedDataDidBecomeAvailable:
में अधिक applicationWillEnterForeground:
में ले जाया गया। इस तरह से मैं ऐप लॉन्च कर सकता हूं, सुनिश्चित करें कि कुछ भी अप्रत्याशित नहीं होता है, होम बटन दबाएं, ऐप खोलें, और सुनिश्चित करें कि सबकुछ काम कर रहा है। चूंकि वास्तविक कोड को एक महत्वपूर्ण दूरी को स्थानांतरित करने और हर बार पांच मिनट का इंतजार करने की आवश्यकता होती है, इसने मुझे यह अनुमान लगाने का एक अच्छा तरीका दिया कि क्या हो रहा था।
एक आखिरी चीज जिसने मुझे फिसल दिया वह मेरा लगातार स्टोर समन्वयक था।
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (_persistentStoreCoordinator != nil) return _persistentStoreCoordinator;
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Test.sqlite"];
NSError *error = nil;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
return _persistentStoreCoordinator;
}
यह शिथिल एप्पल के नमूना कोड है, जो टिप्पणी कि आप सही ढंग त्रुटि को संभालने की ज़रूरत में व्याख्या नहीं करता पर आधारित है: एक ठेठ कार्यान्वयन कुछ इस तरह लग सकता है। मेरा स्वयं का कोड इससे थोड़ा अधिक करता है, लेकिन एक बात जिसे मैंने नहीं सोचा था कि अगर लगातार स्टोर लोड करने में कोई त्रुटि हो, तो यह एक गैर-शून्य परिणाम देगा! यह मेरे सभी अन्य कोड को आगे बढ़ने की इजाजत दे रहा था जैसे कि यह सही तरीके से काम कर रहा था। और यहां तक कि यदि लगातार स्टोर कोऑर्डिनेटर को फिर से बुलाया गया था, तो यह स्टोर को फिर से लोड करने की कोशिश करने के बजाय, एक वैध स्टोर के बिना, एक ही समन्वयक को वापस कर देगा। वहाँ विभिन्न तरीकों से आप इस समस्या से निपटने कर सकते हैं, लेकिन मेरे लिए यह नहीं सेट _persistentStoreCoordinator के लिए सबसे अच्छा लग रहा था जब तक कि यह दुकान को जोड़ने में सक्षम था:
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (_persistentStoreCoordinator != nil) return _persistentStoreCoordinator;
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Test.sqlite"];
NSError *error = nil;
NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if ([coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
_persistentStoreCoordinator = coordinator;
} else {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
return _persistentStoreCoordinator;
}
@robertspacer _persistentStoreCoordinator शून्य इस लाइन पर पर नहीं होगा: अगर ([_persistentStoreCoordinator addPersistentStoreWithType: NSSQLiteStoreType विन्यास: शून्य यूआरएल: storeURL विकल्प: शून्य त्रुटि: और त्रुटि]) { –
@Glen टी हाँ, वह करना चाहिए समन्वयक का संदर्भ रहा है। फिक्स्ड। – robotspacer