开发者

How can I loop through loading data from multiple entities in Core Data in the least amount of code?

开发者 https://www.devze.com 2023-02-08 15:32 出处:网络
I am trying to make loading multiple entities more manageable in code. The code below is attached to an object that can load over 1000 times, so I\'ve put it in a loop and attached a manageable array

I am trying to make loading multiple entities more manageable in code. The code below is attached to an object that can load over 1000 times, so I've put it in a loop and attached a manageable array of entities.

The problem is, because I have no idea if a key is available in singleObject, I am getting a crash on [singleObject valueForKey:@"actor"] when I am on the directors entity. It's becaus开发者_Go百科e the key "actor" doesn't exist. See my code here.

NSArray *entities = [[NSArray alloc] initWithObjects: @"actors", @"directors", @"subtitles", @"audios", nil];

for (NSString *anEntity in entities)
{
    NSEntityDescription *entityDescription = [NSEntityDescription entityForName:anEntity inManagedObjectContext:context];
    [request setEntity:entityDescription];
    NSArray *objects = [context executeFetchRequest:request error:&error];
    if (objects == nil) {
        // error
    }

    for (NSManagedObject *singleObject in objects)
    {
        if (singleObject != nil) 
        {
            if ([singleObject valueForKey:@"actor"] != nil)
            {
                [self.actors addObject:[singleObject valueForKey:@"actor"]];
            }
            else if ([singleObject valueForKey:@"director"] != nil)
            {
                [self.directors addObject:[singleObject valueForKey:@"director"]];
            }
            else if ([singleObject valueForKey:@"subtitle"] != nil)
            {
                [self.subtitles addObject:[singleObject valueForKey:@"subtitle"]];
            }
            else if ([singleObject valueForKey:@"audio"] != nil)
            {
                [self.audios addObject:[singleObject valueForKey:@"audio"]];
            }
        }
    }
}

[entities release];
[request release];'

How can I make this code work, and be vastly expandable, without having to put a bunch of try/catches around everything?


OK I think I found a way that works for me using NSDictionary instead. It works in my situation simply because my entity names are plural (actors) and my attributes are singular (actor). Here is what I came up with:

NSMutableDictionary *entities = [[NSMutableDictionary alloc] init];
[entities setValue:actors forKey:@"actors"];
[entities setValue:directors forKey:@"directors"];
[entities setValue:subtitles forKey:@"subtitles"];
[entities setValue:audios forKey:@"audios"];

for (NSMutableString *aKey in entities)
{
    NSEntityDescription *entityDescription = [NSEntityDescription entityForName:aKey inManagedObjectContext:context];
    [request setEntity:entityDescription];
    NSArray *objects = [context executeFetchRequest:request error:&error];
    if (objects == nil) {
        // error
    }

    for (NSManagedObject *singleObject in objects)
    {
        if (singleObject != nil) 
        {
            if ([singleObject valueForKey:[aKey substringToIndex:[aKey length] - 1]] != nil)
            {
                [[entities valueForKey:aKey] addObject:[singleObject valueForKey:[aKey substringToIndex:[aKey length] - 1]]];
            }
        }
    }
}

Details:

I loop through the keys in the dictionary. I make them mutable so I can take the s off of the end of the key. Then I pull the value (which is an array) from that key and load the array using the key without the s.

Somewhat complicated to read the code, but really slims down the manageability. Now all I need to do is add a new plural entity with matching singular attribute and just add the key/value pair to the dictionary.


I don't know if this will help you or not, because I am not 100% clear on what you are trying to do, but I had a similar problem when importing data from a MySQL database into CoreData. I made extensive use of NSEntityDescription 's methods propertiesByName, attributesByName, and relationshipsByName. In my case, using the field descriptions from the MySQL table, I made sure that my model attributes matched the field names, so instead of needing to do a whole bunch ofif/else tests, I just had the code test to see if [[SomeEntityDescription attributesByName] valueForKey:someFieldName] returned something besides nil. If it did, I set the value for the object I was creating from the imported data using the field name as the key.

You can do something similar for your relationships. if I understand what you are trying to do correctly, by checking against [someEntityDescription relationshipsByName] keys, or, you can get all the relationships that target your entity of interest using relationshipsWithDestinationEntity:(NSEntityDescription *)entity.

0

精彩评论

暂无评论...
验证码 换一张
取 消