簡體   English   中英

子上下文未保存在核心數據中

[英]child context not saving in core data

我正在使用子上下文來保存核心數據對象,但根本沒有保存。 代碼可能是什么問題? 我嘗試通過刪除性能塊並使用performblockAndwait來嘗試,但無法正常工作。 像prepareDataForCustomYearlyOption方法一樣,我還有其他三種分別用於每日,每周和每月的方法,如下所示。

同一代碼在另一個地方工作。

- (NSManagedObjectContext *)backgroundManagedObjectContext
{
    if (_managedObjectContext == nil) {
         [[OUCSCoreDataManager privateInstance]managedObjectContext];
    }
    NSManagedObjectContext *temporaryContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    temporaryContext.parentContext = _managedObjectContext;
    return temporaryContext;
}
- (void)prepareDataForCustomYearlyOption {

    if ([CoreDataManager countForEntity:kCALENDAR_CUSTOM_YEARLY_REPEAT_OPTIONS] != 0) {
        return;
    }

    NSManagedObjectContext *temporaryContext = [[CoreDataManager privateInstance]backgroundManagedObjectContext];

    [temporaryContext performBlock:^{
        @try {
            RepeatOptionsCustomYearly *yearlyOption = [RepeatOptionsCustomYearly insertInManagedObjectContext:temporaryContext];
            yearlyOption.title = NSLocalizedString(k_Yearly, @"REPEAT_OPTIONS_TITILE3");
            yearlyOption.isSelected = [NSNumber numberWithBool:NO];
            yearlyOption.every = [NSNumber numberWithInt:1];
            yearlyOption.startOn = [NSDate date];
            yearlyOption.endsOn = [NSDate date];
            yearlyOption.neverEnds = [NSNumber numberWithBool:NO];
            yearlyOption.summary = @"";
            yearlyOption.everyRange = [NSKeyedArchiver archivedDataWithRootObject:[self getYearRange]];

        } @catch (NSException *exception) {
            NSLog(@"Calendar Manager Exception: --> %@ %@",exception.name, exception.reason);
        }
        // push to parent
        [temporaryContext performBlock:^{
            // push to parent
            NSError *errorTemp;
            if (![temporaryContext save:&errorTemp])
            {
                // handle error
                NSLog(@"Temp MOC Save Error: %@",errorTemp.description);
            }
        }];

    }];
}

您可以嘗試類似的方法,但是錯誤處理不是要遵循的示例:

確保使用主上下文正確設置了私有隊列。

func getPrivateQueueMOC() -> NSManagedObjectContext?
{
    if let moc = delegate.managedObjectContext
    {
        let privateMOC = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.privateQueueConcurrencyType)
        privateMOC.parent = moc
        return privateMOC
    }

    return nil
}

這樣可以確保您保存更改並盡快更新主上下文

func savePrivateContext(privateContext:NSManagedObjectContext)
{
    do {
        try privateContext.save()

        guard let moc = delegate.managedObjectContext else { return }
        moc.performAndWait {
            do {
                try moc.save()
            } catch {
                fatalError("Failure to save context: \(error)")
            }
        }
    } catch {
        fatalError("Failure to save context: \(error)")
    }
}

使用專用隊列的正確方法

func persistStuff(_ stuff:[Dictionary<String, AnyObject>])
{
    if stuff.isEmpty
    {
        return
    }

    if let context = getPrivateQueueMOC()
    {
        context.perform({ () -> Void in
            // Do your stuff here

            if context.hasChanges
            {
                self.savePrivateContext(privateContext: context)
            }

            DispatchQueue.main.async(execute: { () -> Void in
                // Tell UI to update
            })
        })
    }
}

我想您的代碼包含兩個問題。

第一個在backgroundManagedObjectContext方法內部。 永遠不會設置ivar _managedObjectContext

- (NSManagedObjectContext *)backgroundManagedObjectContext
{
    if (_managedObjectContext == nil) {
         _managedObjectContext = [[OUCSCoreDataManager privateInstance]managedObjectContext];
    }
    NSManagedObjectContext *temporaryContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    temporaryContext.parentContext = _managedObjectContext;
    return temporaryContext;
}

第二個可能是您調用了兩次performBlock

- (void)prepareDataForCustomYearlyOption {

    if ([CoreDataManager countForEntity:kCALENDAR_CUSTOM_YEARLY_REPEAT_OPTIONS] != 0) {
        return;
    }

    NSManagedObjectContext *temporaryContext = [[CoreDataManager privateInstance]backgroundManagedObjectContext];

    [temporaryContext performBlock:^{
        @try {
            RepeatOptionsCustomYearly *yearlyOption = [RepeatOptionsCustomYearly insertInManagedObjectContext:temporaryContext];
            yearlyOption.title = NSLocalizedString(k_Yearly, @"REPEAT_OPTIONS_TITILE3");
            yearlyOption.isSelected = [NSNumber numberWithBool:NO];
            yearlyOption.every = [NSNumber numberWithInt:1];
            yearlyOption.startOn = [NSDate date];
            yearlyOption.endsOn = [NSDate date];
            yearlyOption.neverEnds = [NSNumber numberWithBool:NO];
            yearlyOption.summary = @"";
            yearlyOption.everyRange = [NSKeyedArchiver archivedDataWithRootObject:[self getYearRange]];

        } @catch (NSException *exception) {
            NSLog(@"Calendar Manager Exception: --> %@ %@",exception.name, exception.reason);
        }
        // push to parent
        // Comment this ->[temporaryContext performBlock:^{
            // push to parent
            NSError *errorTemp;
            if (![temporaryContext save:&errorTemp])
            {
                // handle error
                NSLog(@"Temp MOC Save Error: %@",errorTemp.description);
            }
        // Comment this -> }];

    }];
}

如果需要,請不要忘記將其保存在temporaryContext上下文的父上下文中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM