문제

나는 "노래"엔티티와 "태그"엔티티를 가지고 있으며 그들 사이에 많은 관계가 있습니다. 노래에는 여러 개의 태그가있을 수 있으며 태그는 여러 곡에 적용될 수 있습니다.

노래에 관련된 특정 태그가 있는지 확인하고 싶습니다. 노래에 태그가 관련된 경우 테이블보기에 확인 표시를 표시하고 싶습니다.

유사한 논리의 경우 Apple "TaggedLocations"샘플 코드에서 다음과 같은 점검이 이루어집니다.

if ([event.tags containsObject:tag]) {
    cell.accessoryType = UITableViewCellAccessoryCheckmark;
}   

데이터베이스에 많은 태그가있는 경우 메모리에 모든 태그를 가져 오는 경우 비효율적 일 수 있습니다. 내가 틀렸다면 저를 바로 잡으십시오.

노래가 Song.tags를 확인하는 대신 특정 태그와 연관되어 있는지 확인하는보다 효율적인 방법이 있습니까?

도움이 되었습니까?

해결책

It's actually pretty easy to do, if completely undocumented. You want to create a fetch request with a predicate that has a set operation. If we imagine that your Tag model has a property called tagValue, the predicate you care about is "ANY tags.tagValue == 'footag'"

NSString *tagSearch = @"footag";

// However you get your NSManagedObjectContext.  If you use template code, it's from
// the UIApplicationDelegate
NSManagedObjectContext *context = [delegate managedObjectContext];

// Is there no shortcut for this?  Maybe not, seems to be per context...
NSEntityDescription *songEntity = [NSEntityDescription entityForName:@"Song" inManagedObjectContext:context];

NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:songEntity];

// The request looks for this a group with the supplied name
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY tags.tagValue == %@", tagSearch];
[request setPredicate:predicate];

NSError *error = nil;
NSArray *results = [context executeFetchRequest:request error:&error];

[request release];

다른 팁

You are correct, using that code will retrieve the entire set and the object comparison may be quite complex, depending on how many properties and relationship are part of the object's entity.

Anyway, you can not avoid a set comparison for inclusion. Probably, the best you can do is to avoid fetching all of the properties/relationships by asking Core Data to retrieve NSManagedObjectID Objects only.

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Tag" inManagedObjectContext:[self managedObjectContext]]]; 
[fetchRequest setResultType:NSManagedObjectIDResultType];

NSManagedObjectID objects are guaranteed to be unique, therefore you can safely use them to check for set inclusion. This should be much more efficient for a performance perspective.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top