2017-06-09 1 views
1

コアデータを削除した後、バックグラウンドでそれを追加するメソッドを作る(SOコアデータを更新することができる)IOS - エラースレッドとコアデータを用いて(対物-C)

(void) resetDatabase { 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){ 
     ConDAO *con = [[ConDAO alloc] init]; 
     DatabaseManager *manager = [DatabaseManager sharedManager]; 
     NSError * error; 
     NSURL * storeURL = [[[manager managedObjectContext] persistentStoreCoordinator] URLForPersistentStore:[[[[manager managedObjectContext] persistentStoreCoordinator] persistentStores] lastObject]]; 
     [[manager managedObjectContext] reset];//to drop pending changes 
     if ([[[manager managedObjectContext] persistentStoreCoordinator] removePersistentStore:[[[[manager managedObjectContext] persistentStoreCoordinator] persistentStores] lastObject] error:&error]) 
     { 
      // remove the file containing the data 
      [[NSFileManager defaultManager] removeItemAtURL:storeURL error:&error]; 
      //recreate the store like in the appDelegate method 
      [[[manager managedObjectContext] persistentStoreCoordinator] addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error];//recreates the persistent store 
     } 
     [self populateDatabase:0 con:con]; 
     NSLog(@"*****************************"); 
     NSLog(@"updating"); 
     NSLog(@"*****************************"); 
     NSTimer *timer = [NSTimer timerWithTimeInterval:60.0 
               target:self 
               selector:@selector(resetDatabase) 
               userInfo:nil repeats:YES]; 
     [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; 
    }); 
} 

しかし、タイマー後実行され、関数は、私は、エラー次のような方法で

EXC_BAD_ACCESS(code = 1, address = 0x38) 

を得る数回実行されます。

- (void)newManagedCaf 
{ 
    cafCards = [[NSManagedObject alloc] initWithEntity:cafDescription insertIntoManagedObjectContext:managedObjectContext]; 
} 

エラーが発生したメソッドがで呼び出されます。

// First the student database is updated 
- (void)populateDatabase:(int)tries con:(ConDAO *)con{ 
    DatabaseManager *manager = [DatabaseManager sharedManager]; 

    //Fetch greatest contact number in local database 
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Caf_student_cards"]; 
    fetchRequest.fetchLimit = 1; 
    fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"contact" ascending:NO]]; 
    NSError *error = nil; 
    id cont = [[[manager managedObjectContext] executeFetchRequest:fetchRequest error:&error].firstObject valueForKey:@"contact"]; 
    int contact = 0; 
    if (cont != nil){ 
     contact = [cont intValue]; 
    } //Pull students newer than the newest student in the local database 
    //NSString *query = [NSString stringWithFormat:@"SELECT caf.user_id, caf.family_number, caf.card_number, caf.suspension_start_date, caf.suspension_end_date, caf.balance, util.room, caf.meal_plan_type, student.special_diet, student.specify_other, users.surname, users.type, users.name, users.contact from(SELECT * from caf_student_cards) AS caf LEFT JOIN (SELECT user_id, special_diet, specify_other FROM students) AS student ON caf.user_id = student.user_id LEFT JOIN (SELECT resource_id AS room, user_id FROM utilizations) AS util ON caf.user_id = util.user_id LEFT JOIN (SELECT surname, name, type, user_id, contact FROM system_users) AS users ON caf.user_id = users.user_id WHERE contact > %d", contact]; 

    NSString *query = @"GetCaf"; 
    [con executePreparedSQLAsync:query Parameter:@[[NSString stringWithFormat:@"%d",contact]] withCompletion:^(NSMutableArray *data, NSError *error){ 
     // Error encountered 
     if(error != nil){ 
      NSLog(@"err: %@", error); 
      // Retry up to twice to execute the query 
      if(tries < 3){ 
       [self populateDatabase:(tries+1) con:con]; 
      } 
      else{ 
       NSLog(@"%s %s %s","\n\n\n",[[error localizedDescription] UTF8String],"\n\n\n"); 
       dispatch_async(dispatch_get_main_queue(), ^{ 
        // Show alert to tell user to reload this page 
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"Error: %@", [error localizedDescription]] message:@"No connection, could not update local data." delegate:self cancelButtonTitle:@"Back" otherButtonTitles:@"Continue", nil]; 
        [alert show]; 
       }); 
      } 
     } 
     else{ 
      // If successful, store the results in the local database 
      for(NSMutableDictionary *result in data){ 
       [manager newManagedCaf]; 
       for (NSString *name in result){ 
        if ([name isEqualToString:@"contact"]){ 
        NSNumber *num = [NSNumber numberWithInteger:[[result valueForKey:name] integerValue]]; 
         [[manager cafCards] setValue:num forKey:name]; 
        } 
        else{ 
         [[manager cafCards] setValue:[result valueForKey:name] forKey:name]; 
        } 
       } 

       [[manager cafCards] setValue:[NSNumber numberWithBool:YES] forKey:@"synced"]; 

      } 
      [[manager cafCards].managedObjectContext save:&error]; 
      if(error != nil){ 
       NSLog(@"Unable to save managed object context."); 
       NSLog(@"%@, %@", error, error.localizedDescription); 
       UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"Error: %@", [error localizedDescription]] message:@"Database not working, try again later or inform IT." delegate:self cancelButtonTitle:@"Back" otherButtonTitles:nil, nil]; 
       [alert show]; 
      } 
      [self getImages:0 con:con withManager:manager]; 
     } 
    }]; 
} 

また、時々私はresetDatabase方法で発生し、次のエラーが表示されます。

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'nil is not a valid store.' 
+1

あなたはそのメソッドを呼び出す場所に投稿できますか? – Siriss

+0

更新された質問。 – King

答えて

1

あなたはあなたの後persistentStoreのmanagedObjectContextを使用しているように見えますストアを削除しました。これがインサート時のクラッシュの原因です。 BAD_ACCESSがnilストアに挿入しようとしています。

ターゲットが9以上の場合は、replacePersistentStoreAtUrlを使用してデータストアを置き換えることができます。

hereのリンク。

+0

replacePersistentStoreAtUrlの使い方が分からない – King

関連する問題