[IOS开发进阶与实战]第一天:CoreData的运行机制

1.数据模型NSManagedObjectModel的建立

 

1.- (NSManagedObjectModel *)managedObjectModel

{

    if (_managedObjectModel != nil) {

        return _managedObjectModel;

    }

    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"CoreDataApp" withExtension:@"momd"];//加载我们的 modeld文件 得到modelURL

    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];  //获得有实体类型的Model

    return _managedObjectModel;

}

 

这里使用了懒加载,就是说第一次加载之后,以后就不会再次加载,除非这个模型被删除了.

然后根据我们文件中的 CoreDataApp.momd 文件名字进行加载,得到 模型的URL.

最后通过URL 就可以得到我们的 managedObjectModel.


2.持久化存储的设置(就相当于我们的所要存储地方的文件)

 

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator

{     //持久化存储控制器

    if (_persistentStoreCoordinator != nil) {

        return _persistentStoreCoordinator;

    }

    

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CoreDataApp.sqlite"];//app的存储位置,得到存储位置的URL

    

    NSError *error = nil;

    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];//加载上面的定义好的模型

    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {

        //设置存储方式,存储位置.得到定义好的 持久化存储位置

        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);

        abort();

    }    

    

    return _persistentStoreCoordinator;

}


首先得到我们的存储位置,制作成 URL .然后依赖于模型 制作我们的持久化管理器.

 

然后把我们的存储位置植入到我们的持久化管理器中.对错误进行处理 .

3.

- (NSManagedObjectContext *)managedObjectContext  

{

    if (_managedObjectContext != nil) {

        return _managedObjectContext;

    }

    

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];

    if (coordinator != nil) {

        _managedObjectContext = [[NSManagedObjectContext alloc] init];   //加载我们的定义好的模型和持久化存储位置,得到我们的上下文.

        [_managedObjectContext setPersistentStoreCoordinator:coordinator];

    }

    return _managedObjectContext;

}

4.

 

 

4.app中断时候的保存

- (void)applicationWillTerminate:(UIApplication *)application

{

    // Saves changes in the application's managed object context before the application terminates.

    [self saveContext];

}



- (void)saveContext

{

    NSError *error = nil;

    NSManagedObjectContext *managedObjectContext = self.managedObjectContext;

    if (managedObjectContext != nil) {

        if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {

             // Replace this implementation with code to handle the error appropriately.

             // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 

            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);

            abort();

        } 

    }

}


5.

 

 

//5.按钮的添加和事件触发

- (void)insertNewObject:(id)sender

{

    NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];

    NSEntityDescription *entity = [[self.fetchedResultsController fetchRequest] entity];

    NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];

    

    // If appropriate, configure the new managed object.

    // Normally you should use accessor methods, but using KVC here avoids the need to add a custom class to the template.

    [newManagedObject setValue:[NSDate date] forKey:@"timeStamp"];

    

    // Save the context.

    NSError *error = nil;

    if (![context save:&error]) {

         // Replace this implementation with code to handle the error appropriately.

         // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 

        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);

        abort();

    }

}

 

//6.请求控制器的实现

- (NSFetchedResultsController *)fetchedResultsController

{

    if (_fetchedResultsController != nil) {

        return _fetchedResultsController;

    }

    

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];//请求

    // Edit the entity name as appropriate.

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:self.managedObjectContext];//依赖上下文实体的名称

    [fetchRequest setEntity:entity]; //对请求设置具体实体的描述

    

    // Set the batch size to a suitable number.

    [fetchRequest setFetchBatchSize:20]; //每次能够取出20条记录.

    

    // Edit the sort key as appropriate.

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timeStamp" ascending:NO];//设置实体属性的key.设定排序规则  

    NSArray *sortDescriptors = @[sortDescriptor];

    

    [fetchRequest setSortDescriptors:sortDescriptors];//添加实体的属性到请求中

    

    // Edit the section name key path and cache name if appropriate.

    // nil for section name key path means "no sections".

    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Master"];//创建请求控制器.

    aFetchedResultsController.delegate = self;

    self.fetchedResultsController = aFetchedResultsController;

    

	NSError *error = nil;

	if (![self.fetchedResultsController performFetch:&error]) {

	     // Replace this implementation with code to handle the error appropriately.

	     // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 

	    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);

	    abort();

	}

    

    return _fetchedResultsController;

} 

7.协议的实现

#pragma mark - Fetched results controller



- (NSFetchedResultsController *)fetchedResultsController

{

    if (_fetchedResultsController != nil) {

        return _fetchedResultsController;

    }

    

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];//请求

    // Edit the entity name as appropriate.

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:self.managedObjectContext];//依赖上下文实体的名称

    [fetchRequest setEntity:entity]; //对请求设置具体实体的描述

    

    // Set the batch size to a suitable number.

    [fetchRequest setFetchBatchSize:20];

    

    // Edit the sort key as appropriate.

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timeStamp" ascending:NO];//设置实体的属性名称

    NSArray *sortDescriptors = @[sortDescriptor];

    

    [fetchRequest setSortDescriptors:sortDescriptors];//添加实体的属性到请求中

    

    // Edit the section name key path and cache name if appropriate.

    // nil for section name key path means "no sections".

    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Master"];//创建请求控制器.

    aFetchedResultsController.delegate = self;//NSFetchedResultsControllerDelegate

    self.fetchedResultsController = aFetchedResultsController;

    

	NSError *error = nil;

	if (![self.fetchedResultsController performFetch:&error]) {

	     // Replace this implementation with code to handle the error appropriately.

	     // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 

	    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);

	    abort();

	}

    

    return _fetchedResultsController;

}    



- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller

{

    [self.tableView beginUpdates];

}



- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo

           atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type

{

    switch(type) {

        case NSFetchedResultsChangeInsert:

            [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];

            break;

            

        case NSFetchedResultsChangeDelete:

            [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];

            break;

    }

}



- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject

       atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type

      newIndexPath:(NSIndexPath *)newIndexPath

{

    UITableView *tableView = self.tableView;

    

    switch(type) {

        case NSFetchedResultsChangeInsert:

            [tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];

            break;

            

        case NSFetchedResultsChangeDelete:

            [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];

            break;

            

        case NSFetchedResultsChangeUpdate:

            [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];

            break;

            

        case NSFetchedResultsChangeMove:

            [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];

            [tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];

            break;

    }

}



- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller

{

    [self.tableView endUpdates];

}



/*

// Implementing the above methods to update the table view in response to individual changes may have performance implications if a large number of changes are made simultaneously. If this proves to be an issue, you can instead just implement controllerDidChangeContent: which notifies the delegate that all section and object changes have been processed. 

 

 - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller

{

    // In the simplest, most efficient, case, reload the table view.

    [self.tableView reloadData];

}

 */



- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath

{

    NSManagedObject *object = [self.fetchedResultsController objectAtIndexPath:indexPath];

    cell.textLabel.text = [[object valueForKey:@"timeStamp"] description];

}


 

 

你可能感兴趣的:(coredata)