Coredata第三課 資料查詢,Coredata資料查詢

來源:互聯網
上載者:User

Coredata第三課 資料查詢,Coredata資料查詢
問題

小明班上最近月考了,老師大明想要給一部分優秀的同學進行獎勵,而另外一部分要進行查漏補缺。大明決定將總分排名前10的,各科成績排名前10的以及排名最後10名的按從高到低的順序找出來。以前大明都是在家用筆一個個划出來。不過最近大明在長沙戴維營教育接受了殘酷的iOS培訓,決定裝逼一把,給自己的“腎6+”開發了一款應用。只要各科老師將成績提交給他,就可以直接看到這些學生的成績了,並且各種曲線、柱狀圖、餅圖。每個學生的情況就好比沒穿衣服一樣”透明“。現在的問題是,大明並不想自己去實現各種篩選和排序演算法。

解決方案

很快大明就想到了戴維營教育的部落格上Core Data除了簡單的存取功能外,還具備各種取資料的方法。

一、資料擷取

Core Data中擷取資料必須通過NSFetchRequest進行。我們有兩種方式擷取NSFetchRequest對象。

  • 通過實體名稱建立NSFetchRequest對象。

這種方式其實就是我們在前面兩篇文章中用來擷取資料的技巧。

NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Person"];//或者NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];NSEntityDescription *entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:context];fetchRequest.entity = entity;
  • 通過模型檔案中建立的請求模版建立。

//使用managedModel擷取fetchRequest模版NSFetchRequest *fetchRequest = [appDelegate.managedObjectModel fetchRequestTemplateForName:@"personFR"];
  • 我們可以指定fetchRequest的結果類型來擷取不同資料,如儲存的對象、結果數目等。
//    NSFetchRequest *fetchRequest = [appDelegate.managedObjectModel fetchRequestTemplateForName:@"personFR"];    //如果需要改變結果的類型,不能使用從模版產生的request對象    NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Person"];    //擷取結果總數    fetchRequest.resultType = NSCountResultType;

不過我們也不只一種擷取結果數目的方式。在Context裡面提供了一系列的操作request的方法,其中就包括了擷取結果數目的功能。

NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Person"];//擷取結果數目NSUInteger count = [context countForFetchRequest:fetchRequest error:nil];
二、篩選結果集

大明已經可以得到所有學生的成績資訊了,接下來要做的就是對它們進行排序和篩選。

  • 給學產生績進行排序
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Person"];//排序描述符,按score降序排列NSSortDescriptor *sort01 = [NSSortDescriptor sortDescriptorWithKey:@"score" ascending:NO];//可以同時按多個屬性進行排序fetchRequest.sortDescriptors = @[sort01];NSArray *result = [context executeFetchRequest:fetchRequest error:nil];if (result) {    _people = [NSMutableArray arrayWithArray:result];    for (NSObject *obj in _people) {        NSLog(@"%@", [obj valueForKey:@"score"]);    }}

結果:

2015-02-04 10:54:16.599 02-02-CoreData01[5832:276345] 992015-02-04 10:54:16.600 02-02-CoreData01[5832:276345] 602015-02-04 10:54:16.600 02-02-CoreData01[5832:276345] 562015-02-04 10:54:16.600 02-02-CoreData01[5832:276345] 45
  • 篩選出成績排名前十的學生
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Person"];NSSortDescriptor *sort01 = [NSSortDescriptor sortDescriptorWithKey:@"score" ascending:NO];fetchRequest.sortDescriptors = @[sort01];//限制只取前十,其實這是有問題的,萬一有重複的分數,後面的就取不到了。fetchRequest.fetchLimit = 10;NSArray *result = [context executeFetchRequest:fetchRequest error:nil];
  • 使用NSPredicate篩選成績高於90分的學生
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"score >= 90"];fetchRequest.predicate = predicate;
進階

上面的這些資料擷取方式都是同步的方式,如果資料量比較大的話,會顯著的影響到程式的效能和使用者體驗。Core Data中也提供了非同步資料擷取功能。

AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;NSManagedObjectContext *context = appDelegate.managedObjectContext;NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Person"];NSSortDescriptor *sort01 = [NSSortDescriptor sortDescriptorWithKey:@"score" ascending:NO];fetchRequest.sortDescriptors = @[sort01];fetchRequest.fetchLimit = 2;//非同步請求NSAsynchronousFetchRequest *asyncRequst = [[NSAsynchronousFetchRequest alloc] initWithFetchRequest:fetchRequest completionBlock:^(NSAsynchronousFetchResult *result) {    for (NSObject *obj in result.finalResult) {        NSLog(@"%@", [obj valueForKey:@"score"]);    }}];//執行非同步請求[context executeRequest:asyncRequst error:nil];

注意: 在使用非同步請求的時候,需要設定NSManagedContext對象的並發類型,否則會出錯。

2015-02-04 12:12:50.709 02-02-CoreData01[6083:300576] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'NSConfinementConcurrencyType context <NSManagedObjectContext: 0x7fb27b72c5f0> cannot support asynchronous fetch request <NSAsynchronousFetchRequest: 0x7fb27b71d750> with fetch request <NSFetchRequest: 0x7fb27b7247a0> (entity: Person; predicate: ((null)); sortDescriptors: ((    "(score, descending, compare:)")); limit: 2; type: NSManagedObjectResultType; ).'

解決辦法是在建立Context對象的時候,設定它的並發類型。

NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];if (!coordinator) {    return nil;}//建立Context對象,並設定並發類型_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];[_managedObjectContext setPersistentStoreCoordinator:coordinator];
參考資料

本文檔由長沙戴維營教育整理。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.