2011-10-08 3 views
5

NSPredicate와 다른 결과를 얻으려고합니다.고유 한 속성을 가진 NSFetchRequest

내 코드 :

NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Members" inManagedObjectContext:context]; 
    request.entity = entity; 
    request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"city" 
                        ascending:YES 
                         selector:@selector(caseInsensitiveCompare:)]]; 

    request.predicate = [NSPredicate predicateWithFormat:@"memberDeleted == %@", [NSNumber numberWithBool:NO]]; 

    NSDictionary *properties = [entity propertiesByName]; 
    request.propertiesToFetch = [NSArray arrayWithObject:[properties objectForKey:@"city"]]; 
    request.returnsDistinctResults = YES; 

    request.fetchBatchSize = 20; 

    NSFetchedResultsController *frc = [[NSFetchedResultsController alloc] initWithFetchRequest:request 
                      managedObjectContext:context 
                      sectionNameKeyPath:nil 
                        cacheName:@"CityCache"]; 
    [request release]; 

    self.fetchedResultsController = frc; 
    [frc release]; 

문제는 결과가 여러 번 같은 도시를 반환한다는 것입니다. 이 엔티티에는 많은 멤버가 있으며 각 멤버에는 속성 "도시"가 있습니다.

내가 뭘 잘못하고 있니?

감사합니다,

RL은

답변

7

NSFetchRequestNSDictionaryResultType에의 resultType 설정해야합니다. 기본값은 실제 객체를 반환하는 것이므로 propertiesToFetch을 무시합니다. @ 알렉스의 도움으로

+0

아마 NSFetchedResultsController'는 일반적으로'NSDictionaryResultType'의 팬이 아닌 '것을 추가해야합니다. 다른 문제가 발생하여 NSFetchedResultsController를 포기해야합니다. – Alex

+0

질문은 결과가 NSDictionary 인 것을 원하지 않는다는 것입니다. 그렇지 않으면 코드 일부를 변경해야합니다. 그것은 다른 방법으로 행할 수 있습니까? –

+0

어떤 물건을 돌려 주길 기대합니까? 핵심 데이터는 객체 그래프에 실제로 존재하는 객체 만 반환 할 수 있습니다. – Alex

6

, 여기에 FRC없이, 마지막 코드입니다 :

NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Members" inManagedObjectContext:self.managedObjectContext]; 
request.entity = entity; 
request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"city" 
                       ascending:YES 
                        selector:@selector(caseInsensitiveCompare:)]]; 

request.predicate = [NSPredicate predicateWithFormat:@"memberDeleted == %@", [NSNumber numberWithBool:NO]]; 

NSDictionary *properties = [entity propertiesByName]; 
request.propertiesToFetch = [NSArray arrayWithObject:[properties objectForKey:@"city"]]; 
request.returnsDistinctResults = YES; 
request.resultType = NSDictionaryResultType; 
request.fetchBatchSize = 20; 

NSError *error = nil; 
NSArray *tempArray = [self.managedObjectContext executeFetchRequest:request error:&error]; 

NSMutableArray *cities = [[NSMutableArray alloc] init]; 
for (int i=0; i < [tempArray count]; i++){ 
    NSDictionary *tempDict = [NSDictionary dictionary]; 
    tempDict = [tempArray objectAtIndex:i]; 

    if ([tempDict objectForKey:@"city"] != nil) 
     [cities addObject:[tempDict objectForKey:@"city"]]; 
} 

//if the tempArray has no nil values, it's more efficient with: 
//NSArray* cities = [tempArray valueForKeyPath:@"city"]; 

self.cityArray = cities; 
[cities release]; 
[request release]; 

이이 도시의 목록이있는 NSArray를 반환합니다.

감사합니다. 공식 문서에서

+1

더 쉽게이 작업을 수행 할 수 있습니다. 다음과 같이하면됩니다 : NSArray * cities = [tempArray valueForKeyPath : @ "city"];'배열의 각 사전에 대해 'city'값을 가져 와서 배열에 넣습니다. – Alex

+1

@Alex, 배열에 nil 값이 없으면 제대로 작동합니다. nil 값이 있으면 충돌합니다. –

+0

죄송합니다. 나는이 문제를 조사하면서 Rui의 "추락"에 대한 논평을 소중하게 여기며 소중하게 생각했다. 그러나 NSArray 클래스 ref는 "valueForKey :"라는 약간 다른 메서드를 나열합니다.이 메서드는 nil 개체에 대해 NSNull 개체를 반환합니다. 그래서 문제가 있어서는 안됩니다. – Wienke

2

:

NSManagedObjectContext *context = <#Get the context#>; 

NSEntityDescription *entity = [NSEntityDescription entityForName:@"<#Entity name#>" inManagedObjectContext:context]; 

NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
[request setEntity:entity]; 
[request setResultType:NSDictionaryResultType]; 
[request setReturnsDistinctResults:YES]; 
[request setPropertiesToFetch :[NSArray arrayWithObject:@"<#Attribute name#>"]]; 

// Execute the fetch. 
NSError *error; 
id requestedValue = nil; 
NSArray *objects = [managedObjectContext executeFetchRequest:request error:&error]; 
if (objects == nil) { 
    // Handle the error. 
} 
관련 문제