سؤال

أنا حاليا تحديث التطبيق استخدام البيانات الأساسية.التطبيق يمكن أن أقول لكم هو "عارض قاعدة البيانات", قاعدة بيانات واحدة فقط قادرة على أن ينظر إليها في وقت واحد.كل قاعدة البيانات يتم الاحتفاظ بها في مجلد منفصل.حاليا يتم تحميل البيانات و تخزينها على شكل مجموعة من ملفات plist.

في النسخة الجديدة أنا في حاجة لتحويل هذه plist قواعد بيانات في قاعدة البيانات الأساسية متجر (متجر واحد لكل قاعدة بيانات.) لقد سبق الإعداد الأساليب التي تخلق منفصلة تخزين الملفات و كريت الكيانات.المشكلة هي أن جميع الكيانات التي يتم حفظها في قاعدة البيانات الأولى أنا خلقت ، وليس "التيار" أو "وأخيرا إنشاء" ملف.

العملية الأساسية أنا باستخدام هي:

//For each database {
//Create the sqlite file and set up NSManagedObjectContext
[MagicalRecord setupCoreDataStackWithStoreNamed:
    [NSURL fileURLWithPath:
    [NSString stringWithFormat:@"%@/%@/%@.sqlite",
    dirPath, directory, directory]]];
NSManagedObjectContext *managedObjectContext = 
    [NSManagedObjectContext MR_contextForCurrentThread];

//Iterate through all the plist files and create the necessary entities.
//Save new entities to file
[managedObjectContext MR_save];
//Clean up all cashes
[MagicalRecord cleanUp];
}

كيف واحد صحيح التبديل بين المتاجر أساسا "الإعادة" كل شيء بين كل التبديل.ويفضل (إن أمكن) باستخدام السحرية سجل.

تحرير:لقد وجدت جزء من المشكلة و إزالة معظم سلوك غير مرغوب فيه.اتضح لا يمكنك موثوق الاتصال [MagicalRecord cleanUp] على خلفية الموضوع.أيضا, فإنه لا يفعل ما أعتقد أنه ينبغي (انظر أدناه).انتهى بي الأمر يدعو إلى الخيط الرئيسي بعد كل "حفظ" إعادة تعيين البيانات الأساسية المكدس.تفعل هذا يخلق سياق جديد لأول ثلاث قواعد البيانات.بعد ذلك يكرر السياق من قاعدة البيانات قواعد بيانات ثلاثة مضت.حتى نفس السياقات الثلاثة تستخدم في حلقة.

هذا ما لدي حاليا;أبدأ عملية من خلال إنشاء مؤشر ترابط خلفية تشغيل التعليمات البرمجية لإنشاء قاعدة بيانات واحدة في الخلفية:

backgroundQueue = dispatch_queue_create("com.BrandonMcQuilkin.myQueue", NULL);
    dispatch_async(backgroundQueue, ^(void) {
        [self createSQLiteDatabase:updateList];
    });

ثم خلق كومة قاعدة البيانات:

- (void)createSQLiteDatabase:(NSArray *)updateList
{
    NSString *directory = [updateList objectAtIndex:0];
    [MagicalRecord setupCoreDataStackWithStoreNamed:
        [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%@/%@.sqlite",
        dirPath, directory, directory]]];
    NSManagedObjectContext *managedObjectContext = 
        [NSManagedObjectContext MR_contextForCurrentThread];
    //Check to see if the stack has reset
    NSLog(@"Before:%i", [[Competition MR_findAllInContext:managedObjectContext] count]);

    //Create and add entities to context...

    //Prepare for next loop
    NSLog(@"After:%i", [[Competition MR_findAllInContext:managedObjectContext] count]);
    [managedObjectContext MR_saveNestedContexts];
    [NSManagedObjectContext MR_resetContextForCurrentThread];

    NSMutableArray *temp = [[NSMutableArray alloc] initWithArray:updateList];
    [temp removeObjectAtIndex:0];

    dispatch_async(dispatch_get_main_queue(), ^(void){
        [self shouldContinueUpdating:temp];
    });

ثم إعادة تعيين كل شيء و أكرر لجميع قواعد البيانات:

- (void)shouldContinueUpdating:(NSArray *)databases
{
    //preform cleanup on main thread and release background thread
    [MagicalRecord cleanUp];
    dispatch_release(backgroundQueue);

    if ([databases count] != 0) {
        backgroundQueue = dispatch_queue_create("com.BrandonMcQuilkin.myQueue", NULL);
        dispatch_async(backgroundQueue, ^(void) {
            [self createSQLiteDatabase:databases];
        });
    }
}

مع اثنين من NSLogs, أحصل على هذا في وحدة التحكم:(باستخدام ستة قواعد البيانات النمط هو نفسه بغض النظر عن كيفية العديد من قواعد البيانات تحويل.)

//First Loop
Before:0
After:308
//Second Loop
Before:0
After:257
//Third Loop
Before:0
After:37
//Fourth Loop
Before:308 
After:541 
//Fifth Loop
Before:257
After:490
//Sixth Loop
Before:37
After:270
... Keep adding to each of the three contexts.

و [MagicalRecord cleanUp] لا تفعل ما تقول انها تفعل.هنا هو ما الأسلوب هو من المفترض أن تفعل.

+ (void) cleanUpStack;
{
[NSManagedObjectContext MR_cleanUp];
[NSManagedObjectModel MR_setDefaultManagedObjectModel:nil];
[NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:nil];
[NSPersistentStore MR_setDefaultPersistentStore:nil];
}

ولكن اتضح أن NSStoreCoordinator كل وقت الحفظ هو نفسه منسق في نفس موقع الذاكرة و كل مخزن هو التسكع.شيء لا يعمل بشكل صحيح...

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

المحلول 2

اتضح أن المشكلة أواجه هو بسبب خلل في MagicalRecord.لقد قدمت بوابة المسألة هنا: https://github.com/magicalpanda/MagicalRecord/issues/270

نصائح أخرى

MagicalRecord قد لا تكون أفضل وسيلة للحصول على هذه الوظيفة بالنسبة لك...

أولا دعونا الصحيح استخدامك setupCoreDataStackWithStoreNamed:الأسلوب.المعلمة يأخذ NSString لا URL أو مسار الملف.MagicalRecord اختيار المسار الصحيح بالنسبة لك و إنشاء المتجر الخاص بك هناك.مما الخاص بك إلى ملف سكليتي من المرجح أن يكون اسمه مع مسار تريده أن يكون.

الشيء التالي, سوف تحتاج إلى حيوي إنشاء الخاصة بك كوريداتا نموذج لهذا الملف.هذا هو نوع من صعب لكنه ممكن.سوف تحتاج إلى اجتياز هذه الملفات بليست, وتفسير الكيانات سمات العلاقات وخلق المقابلة NSEntityDescriptions, NSAttributeDescriptions و NSRelationshipDesctiptions تعبئة وهو NSManagedObjectModel "يدويا".أنت تريد أن تبحث عن طريقة

- [NSManagedObjectModel setEntities:(NSArray *)]

فضلا عن إنشاء طرق NSEntityDescription, NSAttributeDescription و NSRelationshipDescription.

سوف تحتاج أيضا إلى حفظ هذا النموذج في مكان ما حتى لا تضطر إلى إعادة ذلك في كل مرة.لحسن الحظ, مع NSCoding ، لذلك عليك أن تكون قادرا على حفظه إلى القرص.

بعد ذلك سوف ربما تريد تعبئة البيانات الخاصة بك.من هنا MagicalRecord يمكن أن تساعدك.أقترح أن تبحث في استيراد البيانات سهلة بلوق وظيفة كتبتها الكاكاو هي صديقتي

إذا كنت ترغب في "مفتاح متجر" الذي أعتقد يعني كنت ترغب في إنشاء متجر جديد لكل plist لديك, ثم عليك أن هدم كامل البيانات الأساسية كومة لكل ملف.إذا كنت تدير استخدام MagicalRecord لهذا المشروع, سوف تحتاج إلى إلقاء نظرة على [MagicalRecord تنظيف], والبدء من جديد.إن كل نموذج هو نفسه ، يمكن أن تحصل من قبل مع الإفراج عن المستمرة الخاصة بك متجر منسق و إنشاء واحدة جديدة إلى المتجر الخاص بك.ولكن منذ "المخططات" ربما تكون مختلفة, عليك فقط أريد أن الصفر كل شيء والبدء من جديد.

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