Fetching all data from an Entity and printing only

2020-05-11 04:04发布

问题:

I'm trying to fetch all of the data from a particular Core Data Entity and place each record into a string. However the following code only prints the LAST record that it accesses. What am I doing wrong?

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Order" inManagedObjectContext:managedObjectContext];

[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [managedObjectContext executeFetchRequest:fetchRequest error:&error];


NSLog(@"=============================================");
NSLog(@"Generating Data To Be Sent");
for (NSManagedObjectContext * info in fetchedObjects) 

{

    NSLog(@"Client Name: %@", [info valueForKey:@"clientName"]);
    NSLog(@"Client Account Number: %@", [info valueForKey:@"clientAccountNumber"]); 
    NSLog(@"Product Code: %@", [info valueForKey:@"productCode"]);
    NSLog(@"Product Price: %@", [info valueForKey:@"productPrice"]);
    NSLog(@"Product Quantity: %@", [info valueForKey:@"productQuantity"]);
    NSLog(@"Order Total: %@", [info valueForKey:@"orderTotal"]);
    NSLog(@"Order ID : %@", [info valueForKey:@"orderID"]); 
    NSLog(@"Transaction ID: %@", [info valueForKey:@"transactionID"]);
    NSLog(@"Sales Rep ID : %@", [info valueForKey:@"salesRepresentativeID"]);

}

NSString * printedData;
NSString * formattedData;

NSString * clientName;
NSString * clientAccount;
NSString * productCode;
NSString * productQuantity;
NSString * productPrice;
NSString * orderTotal;
NSString * orderID;
NSString * transactionID;
NSString * salesRepID;



for(NSManagedObject * info in fetchedObjects)

{

    clientName = [info valueForKey:@"clientName"];
    clientAccount =  [info valueForKey:@"clientAccountNumber"]; 
    productCode =  [info valueForKey:@"productCode"];
    productPrice =  [info valueForKey:@"productPrice"];
    productQuantity = [info valueForKey:@"productQuantity"];
    orderTotal =  [info valueForKey:@"orderTotal"];
    orderID = [info valueForKey:@"orderID"]; 
    transactionID = [info valueForKey:@"transactionID"];
    salesRepID = [info valueForKey:@"salesRepresentativeID"];


    formattedData = [NSString stringWithFormat:@"|%@|%@|%@|%@|%@|%@|%@|%@|%@|\n",clientName,clientAccount,productCode,productQuantity,productPrice,orderID,transactionID,orderTotal,salesRepID];

    printedData = formattedData;

}

NSLog(@"=============================================");
NSLog(@"Data Generated");
NSLog(@"%@",printedData);
[fetchRequest release];

NSMutableArray *recipients = [[NSMutableArray alloc] initWithCapacity:1];
[recipients addObject:toEmail.text];

MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init];
controller.mailComposeDelegate = self;
[controller setSubject:toSubject.text];
[controller setMessageBody:printedData isHTML:NO];
[controller setToRecipients:recipients];

[self presentModalViewController:controller animated:YES];
[controller release];

回答1:

To fix your initial problem you need to use an NSMutableString. There is no need for formattedData variable.

...
NSMutableString * printedData = [NSMutableString string];
...

for(NSManagedObject * info in fetchedObjects)
{
    ...
    [printedData appendFormat:@"|%@|%@|%@|%@|%@|%@|%@|%@|%@|\n",clientName,clientAccount,productCode,productQuantity,productPrice,orderID,transactionID,orderTotal,salesRepID];
}
...

Your next issue is how inefficient this code is. You are looping over the same collection twice, once to log, once to create a formatted string. You can combine this into one loop. Also all of the variables are defined outside of the scope of the for loop that they are used in, you could simply just declare each one on a line like this.

for(NSManagedObject * info in fetchedObjects)
{
    NSString *clientName = [info valueForKey:@"clientName"];
    NSString *clientAccount =  [info valueForKey:@"clientAccountNumber"];
    ...
    //Log them all
    NSLog(@"%@",clientName);
    NSLog(@"%@",clientAccount);
    ...
}


回答2:

If you are trying to concatenate all of the formattedData strings into a single NSString printedData, that's not what your code is doing, right? In each iteration over your managed objects, you are re-assigning printedData. That's why you only get the last record.

I'm inferring that you want printed data to accumulate all of the formattedData strings derived from your NSManagedObject instances. If that's the case, then you need to declare printedData as an NSMutableString and append formattedData strings to that mutable string in each iteration over your managed objects, e.g.

for( NSManagedObject *info in fetchedObjects )
{
    formattedData = [NSString stringWithFormat://blah blah blah
    [printedData appendString:formattedData];
}