简体   繁体   中英

CoreData and setPropertiesToFetch only returns 1 entity

I have an application that uses CoreData to store Customer entities. Each Customer entity has a customerName , customerID , and other properties.

I then display a list of all the Customers only showing their customerName and customerID .

I can do this fine by executing a fetch request to grab all the Customer entities, however I only need to show the customerName and customerID property.

Question 1: I am trying to use the setPropertiesToFetch to specify only these properties yet every time it only returns 1 object in the array.

Here is what my method looks like:

    NSFetchRequest *fetchRequest = [NSFetchRequest new];


    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Customer" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];

    NSDictionary *entProperties = [entity propertiesByName];

    [fetchRequest setResultType:NSDictionaryResultType];
    [fetchRequest setReturnsDistinctResults:YES];

    [fetchRequest setPropertiesToFetch:[NSArray arrayWithObjects:[entProperties objectForKey:@"customerName"],[entProperties objectForKey:@"customerID"], nil]];

    [fetchRequest setFetchLimit:30];

    NSError *error;
    NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];

    NSLog(@"fetched objects count = %d", [fetchedObjects count]);

    if (error) {
        NSLog(@"Error performing fetch = %@", [error localizedDescription]);
        return nil;
    } else {
        NSLog(@"successful fetch of customers");
        for( NSDictionary* obj in fetchedObjects ) {
            NSLog(@"Customer: %@", [obj objectForKey:@"customerName"]);
        }
        return fetchedObjects;
    }

The one object that is returned is ok so I know that is grabbing at least one Customer objects customerName and customerID . I just need it to return all the Customer objects customerName and customerID .

Question 2:

Is this the best way to be doing this? My thought is that there could be up to 10k+ Customer objects in the database. So it would be memory efficient to only fetch the needed properties to display in the table rather than the entire Customer object.

Then when a customer is selected in the table, I fetch the entire Customer object to display it's details.

However, I've read that it is also good practice to load an entire entity rather than just it's properties if the respective entity could be used in the near future. I guess the idea is that a single fetch request is better than two.

Thank you for your help.

For Question 1: here is my sample code written in swift. I continuously test the CoreData API, and find this calling way. Hope to help you.

let fetchRequest = NSFetchRequest<NSDictionary>(entityName: "Customer")
fetchRequest.resultType = .dictionaryResultType
fetchRequest.propertiesToFetch = [
    #keyPath(Customer.customerID),
    #keyPath(Customer.customerName)
]

let customers: [NSDictionary]
do {
    customers = try managedObjectContext.fetch(fetchRequest)
    customers.forEach {
        print("CustomerID: \($0["customerID"]), CustomerName: \($0["customerName"])")
    }
} catch {
    print(error.localizedDescription)
}

random,

Question 2: It sounds like you are using fetch limits when you should be using batch limits. Batch limits are a basic cursoring mechanism. They are designed to handle memory efficiently.

Wrt Question 1, I'm a big believer in just writing the app in the natural way and then using Instruments and other tools to decide upon performance and memory optimizations. Try getting the app to run correctly first. Then make it fast.

Andrew

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM