CoreData并发 [英] CoreData concurrency

查看:67
本文介绍了CoreData并发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对CoreData持久性有问题(MagicalRecord 2.2,iOS 7.x)
可以在任何线程上创建和使用主对象:

I have an issue with CoreData persistance (MagicalRecord 2.2, iOS 7.x) Main object can be created and used on any thread:

- (Collection *)collection {

    if (!_collection) {
        [MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) {
            _collection = [Collection MR_createInContext:localContext];
            _collection.creationDate = [NSDate date];
            _collection.collectionDescription = @"";
            _collection.name = [CollectionHelper getNameForUnnamedCollection];
        }];
    }

    return _collection;
}

在任何代码位置,我都可以开始在后台线程中向此集合添加资源:

In any place of code i can start adding resources to this collection in background thread:

    if (self.photoSavingBlocksCount == 0) {
        [self beginPhotoSaving];
    }
    self.photoSavingBlocksCount++;
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
    Collection *localCollection = [self.collection MR_inContext:localContext];
    [localCollection addNewResourceForImage:image thumb:thumb gallery:gallery type:RESOURCE_TYPE_IMAGE];
} completion:^(BOOL success, NSError *error) {
    self.photoSavingBlocksCount--;
    if (self.photoSavingBlocksCount == 0) {
        [self endPhotoSaving];
    }
}];

此代码将集合及其资源标记为上载到服务器:

This code marks collection and its resources as uploaded to server:

- (BOOL)markCollectionAsUploaded:(Collection *)collection {
    [MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) {
        Collection *localCollection = [collection MR_inContext:localContext];
        localCollection.uploaded = @YES;
        localCollection.uploadDate = [NSDate date];
    }];
    return YES;
}

此代码工作正常,但如果我在此之前编辑集合,则此代码将失败,收藏不会保存为上载!
换句话说,在下一次获取时,我将获得collection.uploaded == @NO!

This code works fine, but if i edit collection before this, then this code will fail and collection won't be saved as uploaded! In other words on next fetch i will get collection.uploaded == @NO!

此代码保存已编辑的集合

This code saves edited collection

    [MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) {

            Collection *localCollection = [self.collection MR_inContext:localContext];

            NSSet *set = [NSSet setWithArray:self.deletedResources];

            localCollection.uploaded = @NO;
            localCollection.name = ([fieldName.text length] == 0 || [[fieldName.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0)
            ? [CollectionHelper getNameForUnnamedCollection]
            : fieldName.text;
            localCollection.collectionDescription = [fieldDescription.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

            for (Resource *resource in set) {
                Resource *localResource = [resource MR_inContext:localContext];
                [CollectionHelper removeResourceFiles:resource];
                [localResource MR_deleteEntity];
            }
        }];

在日志中,每次保存上下文时我都会看到相同的图片:

In logs i see same picture for every context saving:

-[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x196e2ee0) → Saving <NSManagedObjectContext (0x196e2ee0): *** UNNAMED ***> on *** BACKGROUND THREAD ***
-[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x196e2ee0) → Save Parents? 1
-[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x196e2ee0) → Save Synchronously? 1
-[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x17d83e30) → Saving <NSManagedObjectContext (0x17d83e30): *** BACKGROUND SAVING (ROOT) ***> on *** BACKGROUND THREAD ***
-[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x17d83e30) → Save Parents? 1
-[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x17d83e30) → Save Synchronously? 1

有人可以告诉我一种针对我的情况管理CoreData对象的正确方法吗?我将不胜感激。

Could somebody show me a proper way to manage CoreData objects for my situation? I will appreciate any help.

推荐答案

在您的第一段代码中,您想这样做:

In your first block of code, you want to do this instead:

- (Collection *)collection {

    if (!_collection) {
        [MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) {
            _collection = [Collection MR_createInContext:localContext];
            _collection.creationDate = [NSDate date];
            _collection.collectionDescription = @"";
            _collection.name = [CollectionHelper getNameForUnnamedCollection];
        }];
    }
    _collection = [_collection MR_inContext:self.context];
    return _collection;
}

从保存块返回时,localContext将从内存中丢弃,并且您的对象将无法保存。为避免此问题,您应该然后将此新对象刷新到本地的寿命较长的上下文中。您可以通过不使用块来完全避免这种模式,而直接将其保存到寿命更长的上下文中。

When you return from the save block, the localContext is discarded from memory, and your object will be unable to save. To avoid this problem, you should then refresh this new object into your local, longer lived context. You could avoid this pattern altogether by not using a block and save directly into your longer lived context.

老实说,我没有读完其余的问题,因为应该先解决此问题,以避免模糊的崩溃崩溃……

And, honestly, I didn't read the rest of the question, because this should be cleared up first to avoid obscure crashes down the line...

这篇关于CoreData并发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆