Course 3 Data Query: Coredata data Data Query
Problem
James's class has passed the last month's test. The teacher Daming wants to reward some outstanding students, while the other part wants to check for missing vacancies. Daming decided to find the top 10 in the top 10, top 10 in each subject, and top 10 in the descending order. In the past, Daming used to draw pens one by one. However, Daming recently received a cruel iOS training at Changsha Camp David and decided to install it and develop an application for her "Kidney 6 +. As long as the teacher of each subject submits the score to him, he can directly see the score of these students, and various curves, bar charts, pie charts. Every student is just as transparent as they are without clothes. The problem now is that Daming doesn't want to implement various filtering and sorting algorithms on his own.
Solution
Soon Daming thought of Core Data in the blog of Camp David education. In addition to simple access functions, it also had various Data retrieval methods.
I. Data Acquisition
Core Data must passNSFetchRequest
. There are two ways to obtainNSFetchRequest
Object.
- Create by Object Name
NSFetchRequest
Object.
This method is actually the technique we used to obtain data in the previous two articles.
NSFetchRequest * fetchRequest = [NSFetchRequest response: @ "Person"]; // or NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] init]; NSEntityDescription * entity = [NSEntityDescription entityForName: @ "Person" inManagedObjectContext: context]; fetchRequest. entity = entity;
- Create a request template in the model file.
// Use managedModel to obtain the fetchRequest template NSFetchRequest * fetchRequest = [appDelegate. managedObjectModel fetchRequestTemplateForName: @ "personFR"];
- We can specify the result type of fetchRequest to obtain different data, such as the stored object and result quantity.
// NSFetchRequest * fetchRequest = [appDelegate. managedObjectModel fetchRequestTemplateForName: @ "personFR"]; // if you need to change the result type, you cannot use the request object NSFetchRequest * fetchRequest = [NSFetchRequest response: @ "Person"]; // obtain the total number of results fetchRequest. resultType = NSCountResultType;
However, we have more than one way to get the number of results. The Context provides a series of request operations, including the function of obtaining the number of results.
NSFetchRequest * fetchRequest = [NSFetchRequest fetchRequestWithEntityName: @ "Person"]; // obtain the number of results NSUInteger count = [context countForFetchRequest: fetchRequest error: nil];
Ii. Filter result sets
Daming can get the scores of all the students. Next, sort and filter them.
NSFetchRequest * fetchRequest = [NSFetchRequest descriptor: @ "Person"]; // sort the descriptor by score in descending order. NSSortDescriptor * sort01 = [NSSortDescriptor sortDescriptorWithKey: @ "score" ascending: NO]; // you can sort fetchRequest by multiple attributes at the same time. sortDescriptors = @ [sort01]; NSArray * result = [context executeFetchRequest: fetchRequest error: nil]; if (result) {_ people = [NSMutableArray arrayWithArray: result]; for (NSObject * obj in _ people) {NSLog (@ "% @", [obj valueForKey: @ "score"]) ;}}
Result:
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 response: @ "Person"]; NSSortDescriptor * sort01 = [NSSortDescriptor sortDescriptorWithKey: @ "score" ascending: NO]; fetchRequest. sortDescriptors = @ [sort01]; // The limit is only the top 10. In fact, this is a problem. In case of repeated scores, the latter cannot be obtained. FetchRequest. fetchLimit = 10; NSArray * result = [context executeFetchRequest: fetchRequest error: nil];
- Use NSPredicate to filter students with scores higher than 90
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"score >= 90"];fetchRequest.predicate = predicate;
Advanced
The above data acquisition methods are synchronous. If the data volume is large, it will significantly affect the program performance and user experience. Core Data also provides the asynchronous Data acquisition function.
AppDelegate * appDelegate = (AppDelegate *) [UIApplication sharedApplication]. delegate; NSManagedObjectContext * context = appDelegate. managedObjectContext; NSFetchRequest * fetchRequest = [NSFetchRequest response: @ "Person"]; NSSortDescriptor * sort01 = [NSSortDescriptor response: @ "score" ascending: NO]; fetchRequest. sortDescriptors = @ [sort01]; fetchRequest. fetchLimit = 2; // asynchronous request NSAsynchronousFetchRequest * asyncRequst = [[delealloc] initWithFetchRequest: fetchRequest completionBlock: ^ (optional * result) {for (NSObject * obj in result. finalResult) {NSLog (@ "% @", [obj valueForKey: @ "score"]) ;}}]; // executes the asynchronous request [context executeRequest: asyncRequst error: nil];
Note:When using asynchronous requests, you must set the concurrency type of the NSManagedContext object. Otherwise, an error occurs.
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; ).'
SolutionSet the concurrency type when creating the Context object.
NSPersistentStoreCoordinator * coordinator = [self persistentStoreCoordinator]; if (! Coordinator) {return nil;} // create the Context object and set the concurrency type _ managedObjectContext = [[NSManagedObjectContext alloc] handler: Handler]; [_ managedObjectContext handler: coordinator];
References
This document consistsChangsha Davy EducationSort.