你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> CoreData基礎

CoreData基礎

編輯:IOS開發綜合

基本概念
在CoreData有一些概念剛學習的時候不是很容易理解,還是要單獨拿出來來梳理一下,這樣學後面的內容不會感覺吃力。


♥ 表結構:NSEntityDescription
♥ 表記錄:NSManagedObject

--------------------------------------------------------------------------------

♥ 數據庫存放方式:NSPersistentStoreCoordinator(持久化存儲協調者)
♥ 數據庫操作:NSManagedObjectContext(被管理的對象上下文)
還有一些類NSManagedObjectModel、NSFetchRequest什麼的,具體項目就會有體會,下面來實戰一下。

新建一個項目,項目模板基於“Master-Detail Application”,點擊“Next”按鈕,項目命名為“SimpleCoreData”,並勾選“Use Core Data”,點擊“Next”,選擇項目保存的目錄,點擊“Create”按鈕,項目創建完畢。


代碼分析
比以前創建的簡單項目多了不少代碼,還有xcdatamodeld文件,慢慢分析代碼,AppDelegate.h頭文件中,添加了三個property

@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
再分析AppDelegate.m文件,有對應的三個方法來返回各自對應的對象

#pragma mark - Core Data stack
 
- (NSManagedObjectContext *)managedObjectContext
{
...
    return __managedObjectContext;
}
 
- (NSManagedObjectModel *)managedObjectModel
{
... 
    return __managedObjectModel;
}
 
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
...
    return __persistentStoreCoordinator;
}
這些對象在哪裡被調用的呢,打開MasterViewController.m,在初始化函數中,我們看到通過獲取delegate,再通過delegate調用方法managedObjectContext,這樣就得到了這個NSManagedObjectContext對象,NSManagedObjectContext對象它會跟NSPersistentStoreCoordinator對象打交道,NSPersistentStoreCoordinator會去處理底層的存儲方式。

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        self.title = NSLocalizedString(@"Master", @"Master");
        id delegate = [[UIApplication sharedApplication] delegate];
        self.managedObjectContext = [delegate managedObjectContext];
    }
    return self;
}查詢實體
分析MasterViewController.m的代碼發現以下函數的調用順序。

♥ -tableView:(UITableView *)tableView cellForRowAtIndexPath:
♥ -configureCell:atIndexPath:
♥ -fetchedResultsController
最後是從fetchedResultsController獲取到查詢結果,那就有必要來分析一下

- (NSFetchedResultsController *)fetchedResultsController
{
    // 如果查詢結果已經存在就直接返回__fetchedResultsController
    if (__fetchedResultsController != nil)
    {
        return __fetchedResultsController;
    }
 
    // 1.創建NSFetchRequest對象(相當於SQL語句)
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
 
    // 2.創建查詢實體(相當於設置查詢哪個表)
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];
 
    // 設置獲取數據的批數.
    [fetchRequest setFetchBatchSize:20];
 
    // 3.創建排序描述符,(ascending:是否升序)
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timeStamp" ascending:NO];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
 
    [fetchRequest setSortDescriptors:sortDescriptors];
 
    // 根據fetchRequest和managedObjectContext來創建aFetchedResultsController對象,並設置緩存名字為"Master".
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Master"];
 
    // 設置aFetchedResultsController的委托對象為當前類
    aFetchedResultsController.delegate = self;
    self.fetchedResultsController = aFetchedResultsController;
 
 NSError *error = nil;
    // 獲取第一批數據
 if (![self.fetchedResultsController performFetch:&error])
        {
        // 錯誤處理
     NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
     abort();
 }
 
    return __fetchedResultsController;
}
因為我們設置了aFetchedResultsController的委托NSFetchedResultsControllerDelegate,就要實現它的方法,幸運的是這些方法看起來都像下面這樣,直接復制粘貼就行了。

- (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:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
 
        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
 
        case NSFetchedResultsChangeUpdate:
            [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            break;
 
        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}
 
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    [self.tableView endUpdates];
}添加實體- (void)insertNewObject
{
    // 從NSFetchedResultsController中獲取NSManagedObjectContext對象
    NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
 
    // 從NSFetchedResultsController中獲取實體描述
    NSEntityDescription *entity = [[self.fetchedResultsController fetchRequest] entity];
 
    // 在被管理上下文中插入一個新的NSManagedObject
    NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];
 
    // 字段賦值
    [newManagedObject setValue:[NSDate date] forKey:@"timeStamp"];
 
    // 保存被管理對象上下文,這樣剛才的newManagedObject就被保存了
    NSError *error = nil;
    if (![context save:&error])
    {
        // 錯誤處理.
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
}刪除實體// 從NSFetchedResultsController中獲取NSManagedObjectContext對象
NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
 
// 從被管理對象上下文中刪除MO對象
[context deleteObject:[self.fetchedResultsController objectAtIndexPath:indexPath]];
 
// 保存被管理對象上下文
NSError *error = nil;
if (![context save:&error])
{
    // 錯誤處理
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}
這個刪除對象為什麼沒有處理TableView的代碼,因為我們實現NSFetchedResultsControllerDelegate委托,當對象上下文發生變化時NSFetchedResultsControllerDelegate的實現方法會處理這些事情。

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved