ios – 使用线程和核心数据时的错误(objective-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.' 

看起来您在删除商店后正在使用persistentStore的managedObjectContext。 这是插入时崩溃的原因。 BAD_ACCESS正试图插入到零商店。

如果您的目标是9+,则可以使用replacePersistentStoreAtUrl来replace数据存储。

链接相关的问题在这里 。