在ios中的NSManagedObject中更新数据时应用程序崩溃

时间:2014-09-07 04:34:09

标签: ios objective-c core-data nsoperationqueue

嗨,我的一个申请表。我正在使用队列从服务器下载文件,文件下载完成后我更新了coredata中的状态(同步类型)。核心数据db app中的更新状态不断崩溃。

以下是我在我的应用中使用的代码

 **In Download file method**

    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadfileinThread:) object:params] ;

    [operation addObserver:self forKeyPath:@"isFinished" options:0 context:nil];

    [downloadQueue addOperation:operation] ;


    **In Download file in Thread. (Here actual file will download)**

    -(void) downloadfileinThread: 

    {

    [self UpdateDatabase:file with:updatesArray1] ; //updatesArray1 contains dictionaries (Syncstatus:0 like this)

    }

    **DB updation**

    -(void) UpdateDatabase:(id)_object with:(NSMutableArray *)updatesArray
    {

    NSManagedObjectContext *threadManagedObjectContext = [self myManagedContext] ;

[[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextObjectsDidChangeNotification object:threadManagedObjectContext] ;

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mergeContextChangesForNotification:) name:NSManagedObjectContextObjectsDidChangeNotification object:threadManagedObjectContext];

  NSManagedObject *object = [threadManagedObjectContext objectWithID:[_object objectID]] ;

            if (updatesArray)

            {
            for (NSDictionary *updatedDic in updatesArray)

            {

         [object setValue:[[updatedDic allValues]lastObject] forKey:[[keyValue allKeys]lastObject]];

             }

             NSError *error;
             bool result = [threadManagedObjectContext save:&error];
                 if (!result)
                 {
                     NSLog(@" error saving context, %@, %@", error, error.userInfo);
                 }
            }
    }        

崩溃消息:由于未捕获的异常而终止应用' NSGenericException',原因:' * 集合< __ NSDictionaryM:0xd01b9e0>在被列举时被突变。'

请帮我解决这个问题。

2 个答案:

答案 0 :(得分:0)

我不确定你在这里遇到什么问题,因为我在你的代码中找不到任何明显的东西,但一般来说,当一个可变对象(数组或字典)得到更新(添加/删除对象)时会出现这个问题在一个循环中,它被读取。尝试避免代码中的任何此类活动。

另一个建议是。代码中的Add Exception break point。并使用断点运行代码。这将指示您遇到此异常的确切行。并附上该行的代码,以便进一步清算。

答案 1 :(得分:0)

您获得的例外:

* Collection <__NSDictionaryM: 0xd01b9e0> was mutated while being enumerated.

表示NSMutableDictionary实例在枚举时已更改。 __ NSDictionaryM 中的 M 表示它是一个可变字典。在您的答案中包含的代码中,我可以在一个地方枚举字典:

[object setValue:[[updatedDic allValues]lastObject] forKey:[[keyValue allKeys]lastObject]];

当调用[updatedDic allValues]时,Foundation使用快速枚举来组成值数组。虽然Foundation正在执行此操作,但字典对象正在应用程序的其他位置更改(变异)。您的程序的任何部分都可能会调用此方法构建NSMutableArray NSMutableDictionaryNSMutableDictionary,称为此方法,然后继续修改这些NSMutableDictionary。这就是造成问题的原因。在枚举时不要更改集合。一个非常简单的解决方法是将[someArray addObject:[someDictionary copy]];不可变副本添加到可变数组中:

{{1}}

完全可能的是,异常实际上发生在其他地方,没有堆栈跟踪,这是不可能的。