باستخدام NSMigrationManager لإلحاق البيانات في مخزن استمرار البيانات الأساسية
سؤال
وأود أن إلحاق محتويات من ملف سكليتي واحد (التي تم إنشاؤها باستخدام البيانات الأساسية مع نموذج A) إلى مخزن سكليتي آخر المستخدمة من قبل طلبي (الذي يستخدم نفس نموذج A). والفكرة هي أن بسرعة استيراد كميات كبيرة من البيانات.
والمشكلة أواجهها هي أن رمز أدناه فقط يعمل مرة واحدة. عندما أحاول تشغيل نفس رمز مرتين وتطبيق تحطم في خط I ملحوظ مع تعليقي. أي مساعدة سيكون موضع تقدير كبير.
NSError **err;
NSURL *importURL = [NSURL fileURLWithPath:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: @"import.sqlite"]];
NSURL *storeURL = [NSURL fileURLWithPath:[[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"applicationdata.sqlite"]];
NSMigrationManager *migrator = [[NSMigrationManager alloc] initWithSourceModel:[self managedObjectModel] destinationModel:[self managedObjectModel]];
NSMappingModel *mappingModel = [NSMappingModel inferredMappingModelForSourceModel:[self managedObjectModel] destinationModel:[self managedObjectModel] error:err];
NSError **err2;
// the following line crashes when the whole block is ran twice
[migrator migrateStoreFromURL:importURL
type:NSSQLiteStoreType
options:nil
withMappingModel:mappingModel
toDestinationURL:storeURL
destinationType:NSSQLiteStoreType
destinationOptions:nil
error:err2];
NSLog(@"import finished");
[migrator release];
المحلول
وأرى خطأ واحد في هذا الرمز على الفور، والتي لديها ما تفعله مع حجة الخطأ أن استدعاء الأسلوب. وNSError**
يعني أنك تريد أن تعطي طريقة عنوان لNSError*
، التي سوف تستخدم لكتابة إشارة إلى كائن خطأ (في حالة حدوث خطأ). الحق الآن كنت مجرد مرور في مؤشر غير مهيأ التي يمكن أن تشير إلى شيء صالح أو يمكن أن تشير إلى مجموع القمامة، اعتمادا على ما يحدث أن تكون على المكدس في ذلك الوقت. وطريقة تطبيق الترقية في الكتابة إلى هذه النقطة، وأحيانا مع أي تأثير سوء واضح، ولكن في بعض الأحيان يؤدي في حادث تحطم طائرة، وكأنك ترى. سيكون رمز لذلك تبدو هذه:
NSError *err2 = nil; //you want to initialize to nil, in case method doesn't modify your pointer at all (i.e. no error occurs)
//the method also returns a BOOL indicating success/failure
if (![migrator migrateStoreFromURL:importURL
type:NSSQLiteStoreType
options:nil
withMappingModel:mappingModel
toDestinationURL:storeURL
destinationType:NSSQLiteStoreType
destinationOptions:nil
error:&err2])
{
//handle the error
}
نصائح أخرى
وبفضل بريان لافتا من ذلك.
وانتهى بي الأمر مجرد إضافة الملف سكليتي إضافية إلى مخازن المستمرة من المكدس، يعمل بشكل جيد للغاية ويسمح لنا للحد وقت لاحق fetchRequest إلى مخازن الفردية:
NSError *error = nil;
NSURL *url = SOME_FILEPATH_URL;
NSPersistentStore *newStore = [persistentStoreCoordinator
addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:url
options:opt
error:&error];
ونحافظ على القاموس جميع persistentStores للرجوع إليها فيما بعد.