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 Translation
entity with a predicate like:
NSPredicate *p=[NSPredicate predicateWithFormat:@"code==%@ AND langauge.text==%@",codeForTranslation,languageCode];
精彩评论