2011-10-08 16 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は無視されます。 @Alexの助けを借りて

+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、配列にゼロの値がない場合は問題ありません。何もない値があれば、クラッシュします。 –

+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. 
} 
関連する問題