开发者

use NSPredicate to strip ToMany relationships on coredata

I have a coredata table with a list of 32 languages. Each language has a relationship one-to-many with translations, which contains 32 translations of the associated language.

For example English would be:

Language.code = @"EN";
//english translation
Language.Translation.code = @"EN";
Language.Translation.text = @"english";
//italian translation
Language.Translation.code = @"IT";
Language.Translation.text = @"inglese";
...

End French would be:

Language.code = @"FR";
//english translation
Language.Translation.code = @"EN";
Language.Translation.text 开发者_开发技巧= @"french";
//italian translation
Language.Translation.code = @"IT";
Language.Translation.text = @"francese";
...

And so on to form a matrix of 32x32.

I use this through out my app but at some point I need to show a tableview with each language in his own let's say idiom (english, français, italiano, español, 日本人, ...). To do this I did use the usual NSFetchRequest and then on tableview cellForRowAtIndexPath: I run an NSPredicate like:

@"Language.code = Language.Translation.code"

The result is quite memory wasting, so I was wondering if there is a way to strip the 31 translations in the relationship I do not use while I am doing the NSFetchRequest. I tryed something like:

@"ANY LangTranslations.translationCode = code"

but this is not stripping, it's just checking! Is there a better way to do it?


It sounds like you have a datamodel something like this:

Language{
    code:string
    translations<-->>Translation.language
}

Translation{
    code:string
    text:string
    language<<-->Language.translations
}

If you already have the Language object, then you don't have to fetch the related Translation objects you just have to walk the relationship. For any particular Language object, the value of translations will return a NSSet of all the related translations. Once you have the set, you can sort it into an array for display in a tableview.

Update:

From comment:

Basically I would like to retrieve each Language object with only one translation out of the 32 it has.

Core Data doesn't work like that. A fetch returns instances of one entity and then you walk that entities relationships to find other instances of related entities. However, you need to be clear on what object you really want. In this case do you want a Language object with certain Translations object/s or do you want a Translations object with a specific Language object?

If the former, the first step is to fetch the Language object you want with a predicate of:

NSPredicate *p=[NSPredicate predicateWithFormat:@"code=%@",languageCode];

... that will give you the english Language object. Then you just ask the Language for the appropriate Translation object:

NSPredicate *p=[NSPredicate predicateWithFormat:@"code=%@",languageCode];
Translation *t=[[aLanguageObj.translations filteredSetUsingPredicate:p] anyObject];

If you have to do this a lot and you have NSManagedObject subclasses for Language and Translation, you could warp the previous code up in a method on the Language class that would handle this for you:

-(Translation *) translationForCode:(NSString *) languageCode; 

... and uses it like:

cell.textLabel.text=[[aLanguageObj translationForCode:languageCode].text];

If you want a Translation object related to a specific Language object, then you would run a fetch on the Translationentity with a predicate like:

NSPredicate *p=[NSPredicate predicateWithFormat:@"code==%@ AND langauge.text==%@",codeForTranslation,languageCode];
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜