1

別のオブジェクトが追加されたときにCoreDataのいくつかの値を更新するために使用している次のコードがあります。

//Create new receipt
        Receipt *receipt = [[Receipt alloc] init];
        receipt.project = self.projectLabel.text;
        receipt.amount = self.amountTextField.text;
        receipt.descriptionNote = self.descriptionTextField.text;
        receipt.business = self.businessNameTextField.text;
        receipt.date = self.dateLabel.text;
        receipt.category = self.categoryLabel.text;
        receipt.paidBy = self.paidByLabel.text;
        receipt.receiptImage1 = self.receiptImage1;
        //Need to set this to 2
        receipt.receiptImage2 = self.receiptImage1;
        receipt.receiptNumber = @"99";

        int count = 0;
        int catCount = 0;

    for (Project *p in appDelegate.projects)
            {
                if ([p.projectName isEqualToString:receipt.project]){
                    double tempValue = [p.totalValue doubleValue];
                    tempValue += [receipt.amount doubleValue];
                    NSString *newTotalValue = [NSString stringWithFormat:@"%.02f", tempValue];
                    NSString *newProjectName = p.projectName;
                    //remove entity from Core Data
                    NSFetchRequest * allProjects = [[NSFetchRequest alloc] init];
                    [allProjects setEntity:[NSEntityDescription entityForName:@"Project" inManagedObjectContext:appDelegate.managedObjectContext]];
                    [allProjects setIncludesPropertyValues:NO]; //only fetch the managedObjectID

                    NSError * error = nil;
                    NSArray * projectsArray = [appDelegate.managedObjectContext executeFetchRequest:allProjects error:&error];

                    //Delete product from Core Data
                    [appDelegate.managedObjectContext deleteObject:[projectsArray objectAtIndex:count]];

                    NSError *saveError = nil;
                    [appDelegate.managedObjectContext save:&saveError];

                    [appDelegate.projects removeObjectAtIndex:count];

                    NSLog(@"Removed project from Core Data");

                    //Insert a new object of type ProductInfo into Core Data
                    NSManagedObject *projectInfo = [NSEntityDescription
                                                    insertNewObjectForEntityForName:@"Project" 
                                                    inManagedObjectContext:appDelegate.managedObjectContext];

                    //Set receipt entities values
                    [projectInfo setValue:newProjectName forKey:@"name"];
                    [projectInfo setValue:newTotalValue forKey:@"totalValue"];

                    if (![appDelegate.managedObjectContext save:&error]) {
                        NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
                    }

                    NSLog(@"Added Project to Core Data");

                    Project *tempProject = [[Project alloc] init];
                    tempProject.projectName = [projectInfo valueForKey:@"name"];
                    tempProject.totalValue = [projectInfo valueForKey:@"totalValue"];

                    [appDelegate.projects addObject:tempProject];

                }
                count++;
            }

            for (Category *c in appDelegate.categories){

                if ([c.categoryName isEqualToString:receipt.category]){

                    double tempValue = [c.totalValue doubleValue];
                    tempValue += [receipt.amount doubleValue];
                    NSString *newTotalValue = [NSString stringWithFormat:@"%.02f", tempValue];
                    NSString *newCategoryName = c.categoryName;

                    //remove entity from Core Data
                    NSFetchRequest * allCategories = [[NSFetchRequest alloc] init];
                    [allCategories setEntity:[NSEntityDescription entityForName:@"Category" inManagedObjectContext:appDelegate.managedObjectContext]];
                    [allCategories setIncludesPropertyValues:NO]; //only fetch the managedObjectID

                    NSError * categoriesError = nil;
                    NSArray * categoriesArray = [appDelegate.managedObjectContext executeFetchRequest:allCategories error:&categoriesError];

                    //Delete product from Core Data
                    [appDelegate.managedObjectContext deleteObject:[categoriesArray objectAtIndex:catCount]];
                    NSError *categorySaveError = nil;
                    [appDelegate.managedObjectContext save:&categorySaveError];

                    [appDelegate.categories removeObjectAtIndex:catCount];

                    NSLog(@"Removed category from Core Data");
                    NSError * error = nil;
                    //Insert a new object of type ProductInfo into Core Data
                    NSManagedObject *categoryInfo = [NSEntityDescription
                                                     insertNewObjectForEntityForName:@"Category" 
                                                     inManagedObjectContext:appDelegate.managedObjectContext];

                    //Set receipt entities values
                    [categoryInfo setValue:newCategoryName forKey:@"name"];
                    [categoryInfo setValue:newTotalValue forKey:@"totalValue"];

                    if (![appDelegate.managedObjectContext save:&error]) {
                        NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
                    }

                    NSLog(@"Added Category to Core Data");

                    Category *tempCategory = [[Category alloc] init];
                    tempCategory.categoryName = [categoryInfo valueForKey:@"name"];
                    tempCategory.totalValue = [categoryInfo valueForKey:@"totalValue"];

                    [appDelegate.categories addObject:tempCategory];
                }
                catCount++;

            }

このコードはエラーを出します:

「...列挙中に変更されました」。

誰かが理由を説明できますか?また、私が達成しようとしていることを行うためのより良いアプローチはありますか?

4

2 に答える 2

5

表示されているエラーは正確です。問題は、コレクションを反復処理しながらコレクションを変更(変更)していることです。基本的に、あなたは次のような形をしています。

for (Project *p in appDelegate.projects) {
   ...
   [p addObject: X]
}

これは許可されていません。

簡単な解決策の1つは、追加するオブジェクトの新しいコレクションを作成し、それらをループの外側の元のコンテナーに追加することです。何かのようなもの:

NSMutableArray *array = [NSMutableArray array];
for (Project *p in appDelegate.projects) {
   ...
   [array addObject:X];
}
[p addObjects:array];

ちなみに、「列挙中に変異しました」というエラーテキストをグーグルで検索しましたか?グーグルだけでこの一般的な問題の答えが見つからなかったとしたら、私は驚きます。

また、エラーメッセージを投稿するときは、行の一部だけでなく、行全体を投稿すると便利です。

于 2012-04-17T09:30:26.893 に答える
0

appDelegate.projectsここでは、for-eachループでアイテムを繰り返し処理しながら、アイテムを追加および削除しています。

[appDelegate.projects removeObjectAtIndex:count];
// ...
[appDelegate.projects addObject:tempProject];

そして同じことappDelegate.categories

[appDelegate.categories removeObjectAtIndex:count];
// ...
[appDelegate.categories addObject:tempProject];

AFAIK、そのような場合は、単純なforループを使用し、インデックスを使用して配列にアクセスする必要があります。

于 2012-04-17T09:28:08.637 に答える