0

TransactionCore Data アプリケーションに sというオブジェクトをいくつか追加しています。これらのトランザクションはアカウントにリンクされています。

すべての取引が保存されたら、口座の金額を更新したいと思います。同時実行例外が発生する場合がある

「列挙中にコレクションが変異しました」

アットNSArray *matches = [managedObjectContext executeFetchRequest:request error:&error];ライン インaccountManagedObjectWithIdメソッド。

//TransactionsManager

- (BOOL)addRepeatTransaction:(Transaction *)transaction{

    Account *accountTrx = transaction.account;
    double accountAmount = accountTrx.amount;
    for (int i =0; i<nbRepeat; i++){
         accountAmount +=transactionBiz.amount;
        [[Persister instance] registerTransaction:transaction];
    }
    [[Persister instance]editAmountAccount:transaction.account amount:accountAmount];
    [[Persister instance]saveContext];

    return YES;
}

//Persister

-(id)init {
    if (self = [super init]){
        managedObjectContext = [appDelegate managedObjectContext];
        return self;
    }
    return nil;
}

-(BOOL)registerTransaction:(Transaction *)transaction {
    TransactionManagedObject *transactionsRow = (TransactionsManagedObject *)[NSEntityDescription insertNewObjectForEntityForName:@"Transactions" inManagedObjectContext:managedObjectContext];

    transactionsRow.idTransaction =  [NSNumber numberWithInt:transaction.idTransaction];
    transactionsRow.name = transaction.name;
    transactionsRow.amount = [NSNumber numberWithDouble:transaction.amount];
    [...]
    transactionsRow.account = [[Finder instance] accountManagedObjectWithId:transaction.account.idAccount];

    return YES;
}

-(BOOL)editAmountAccount:(Account *)asset amount:(double)amount {
    AccountManagedObject *accountRow = [[Finder instance] accountManagedObjectWithId:account.idAccount];

    accountRow.amount = [NSNumber numberWithDouble:amount];
    return YES;
}

-(AccountManagedObject *)accountManagedObjectWithId:(NSInteger)idAccount {

    NSFetchRequest *request = [[NSFetchRequest alloc]init];
    [request setEntity:[NSEntityDescription entityForName:@"Accounts" inManagedObjectContext:managedObjectContext]];

    //Predicate
    NSString *recordedIdAccount = @"idAccount";
    NSNumber *numberIdAccount = [NSNumber numberWithInt:idAccount];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", recordedIdAccount,numberIdAccount];
    [request setPredicate:predicate];

    //Execute
    NSError *error;
    NSArray *matches = [managedObjectContext executeFetchRequest:request error:&error];
    NSInteger nbResult = [matches count];
    if(nbResult==1){
        return [matches objectAtIndex:0];
    }
    if(nbResult==0){
        [...]
        return nil;
    }
    if(nbResult>0){
        [...]
        return nil;
    }
    return nil;
}

//UI call
[...]
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
     //Save
     [[TransactionsManager instance] addRepeatTransaction:transactionToAdd];

     dispatch_async(dispatch_get_main_queue(), ^{

          //Call the delegate
          [self.delegate theSaveButtonOnTheAddTransactionTVCWasTapped:self];
      });
});

@バレンティン・ラドゥ

私はそれを試しましたが、問題は残っています。managedObjectContext追加するたびに forを設定する必要があります。これは機能していますが、アプリケーションの速度が低下します。それは正しい方法ですか?

-(BOOL)registerTransaction:(Transaction *)transaction{
    NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init];
   [moc setPersistentStoreCoordinator:[[self managedObjectContext] persistentStoreCoordinator]];


    TransactionsManagedObject *transactionsRow = (TransactionsManagedObject *)[NSEntityDescription insertNewObjectForEntityForName:@"Transactions" inManagedObjectContext:moc];

    transactionsRow.idTransaction =  [NSNumber numberWithInt:transaction.idTransaction];
    transactionsRow.name = transaction.name;
    transactionsRow.amount = [NSNumber numberWithDouble:transaction.amount];
    [...]
    transactionsRow.account = [[Finder instance] accountManagedObjectWithId:transaction.account.idAccount andManagedContext:moc]];

    NSError *error = nil;
    if (![moc save:&error]) {
        [[ErrorManager instance] addError:error];
        return NO;
    }

    return YES;
}
4

1 に答える 1

6

コアデータオブジェクトで並列操作を実行している場合、これは間違っています。スレッドごとにコンテキストがあり、保存するたびにコンテキストをマージする必要があります。Apple のコア データ ガイドラインでは、これについて詳しく説明しています。

于 2012-12-10T17:06:15.343 に答える