开发者

saving NSManagedObjectContext causes the app to wait infinitely

开发者 https://www.devze.com 2023-03-23 05:09 出处:网络
Why is it that everytime I call save on my NSManagedObjectContext: -(NSManagedObjectContext*)managedObjectContext {

Why is it that everytime I call save on my NSManagedObjectContext:

-(NSManagedObjectContext*)managedObjectContext {
    NSMutableDictionary* threadDictionary = [[NSThread currentThread] threadDictionary];
    NSManagedObjectContext* backgroundThreadContext = [threadDictionary objectForKey:RKManagedObjectStoreThreadDictionaryContextKey];
    if (!backgroundThreadContext) {
        backgroundThreadContext = [self newManagedObjectContext];
        [threadDictionary setObject:backgroundThreadContext forKey:RKManagedObjectStoreThreadDictionaryContextKey];
        [backgroundThreadContext release];

        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(mergeChanges:)
                                                     name:NSManagedObjectContextDidSaveNotification
                                                   object:backgroundThreadContext];
    }
    return backgroundThreadContext;
}

- (NSError*)save {
    NSManagedObjectContext* moc = [self managedObjectContext];
    NSError *error = nil;

    @try {
        if (![moc save:&error]) { //breakpoint in here

    //some code
}

the app seems to be waiting forever and never got back to resume it's execution? Here's what I mean in a video. Can this be possibly caused because something is wrong with the entity/relationship model?

Here's a screenshot of the leaks 开发者_开发百科instruments, I don't see any leaks, but it seems that the app is allocating something that builds up:

saving NSManagedObjectContext causes the app to wait infinitely


Have you tried ditching your multi-threading code to see if it works? My guess would be that you're mixing up threads here and accessing/saving the MOC from different threads. Managing threads manually is a PITA, you should try switching to Grand Central Dispatch.

I would also give your main MOC its own accessor so you can make sure it isn't called from background threads, and have some: - (NSManagedObjectContext*)newBackgroundMOC; and - (void)saveBackgroundMOC:(NSManagedObjectContext*)context; methods to quickly create and save MOCs from background queues/threads:

dispatch_async(my_queue, ^{
    NSManagedObjectContext *context = [self newBackgroundMOC]; // create context, setup didSave notification to merge with main MOC, etc

    // modify context

    [self saveBackgroundMOC:context]; // main MOC gets updated
});

Migrating to GCD is a bit of work, but in the long run you'll see it's much more pleasant to work with. It goes without saying that it's also the most modern and recommended by Apple way to deal with threads.

0

精彩评论

暂无评论...
验证码 换一张
取 消