2012-02-14 1 views
0

私は今かなりの間、次の問題を抱えています: 私はNSManagedObjectサブクラスオブジェクトを含む2つのNSArraysを持っています。 それらは異なるソースから供給されますが、それらのオブジェクトは同じプロパティ/値を持っています。 ここでは、配列Aに配列Bのオブジェクトが含まれているかどうかをチェックします。 残念ながらNSArrayのcontainsObject-methodはここでは動作しません。 私はそれが各オブジェクトの等価チェックのためのIDテストを使用すると思いますか?お互いのオブジェクト(NSManagedObject)を含むための2つのNSArraysを確認してください

誰かが手掛かりを持っていますか?

NSSetsで私のオブジェクトをカプセル化しようとしても、私の比較方法としてmember:を使用しましたが、これはうまくいきませんでした。特にNSManagedObjectサブクラスのisEqualなどをオーバーライドしないでください。ここで

は、コードスニペットです:任意のヒントを事前に

//manufacturers is an array, parsed out of some xml here... 

for(Manufacturer *manu in [fetchedResultsController fetchedObjects]) 
{ 
    if(![manufacturers containsObject:manu]) 
    { 
     NSLog(@"Deleting %@", manu.name); 
     [self.mContext deleteObject:manu]; 
    } 
} 

for(Manufacturer *manu in manufacturers) 
{ 
    if(![[fetchedResultsController fetchedObjects] containsObject:manu]) 
    { 
     NSLog(@"Adding %@", manu.name); 
     [newArray addObject:manu]; 
    } 
} 

感謝;)

答えて

0

私はこれが動作するかどうかわからないんだけど、あなたはdictionaryWithValuesForKeys:で取得辞書に一致するように試みることができます。

このような何か:

NSArray *keysToCompare = [NSArray arrayWithObjects:@"FooAttribute", @"BarAttribute", nil]; 

// create an array with the dictionary representation of the managedObject 
NSMutableArray *fetchedObjectsDictionaries = [NSMutableArray arrayWithCapacity:[[fetchedResultsController fetchedObjects] count]]; 
for (NSManagedObject *object in [fetchedResultsController fetchedObjects]) { 
    NSDictionary *dictionaryRepresentation = [object dictionaryWithValuesForKeys:keysToCompare]; 
    [fetchedObjectsDictionaries addObject:dictionaryRepresentation]; 
} 

// another array with dictionaries for managedObjects 
NSMutableArray *manufacturersDictionaries = [NSMutableArray arrayWithCapacity:[manufacturers count]]; 
for (NSManagedObject *object in manufacturers) { 
    NSDictionary *dictionaryRepresentation = [object dictionaryWithValuesForKeys:keysToCompare]; 
    [manufacturersDictionaries addObject:dictionaryRepresentation]; 
} 

// compare those dictionaries 
for (NSInteger i = 0; i < [fetchedObjectsDictionaries count]; i++) { 
    NSDictionary *dictionary = [fetchedObjectsDictionaries objectAtIndex:i]; 
    if (![manufacturersDictionaries containsObject:dictionary]) { 
     // get the corresponding managedObject 
     NSManagedObject *object = [[fetchedResultsController fetchedObjects] objectAtIndex:i]; 
     [newArray addObject:object]; 
    } 
} 

それはあなたがあなた自身のisEqualToManufacturer:方法を記述して、手動トラフに配列を列挙することができます動作しない場合。

+0

これらの配列にオブジェクトが複数含まれていると、これは非常に高価で遅くなります。 –

0

同じメモリアドレス、管理オブジェクトIDの等価性、および値の等価性の3つのタイプがあります。あなたの現在のコードは、オブジェクトが同じメモリアドレスを共有しているかどうかをチェックしています。これはあなたが興味のあるものではない可能性が最も高いです。管理対象オブジェクトid等価メソッドを使用すると、製造元がデータベース内の同じ行を指しているかどうかを確認できます。値の等しい値を使用すると、2つの製造元が共有された値に基づいて等しいかどうかを確認できます。以下は、NSManagedObjectIDの等価性をチェックする方法です。それはへの-[NSArray containsObject:]呼んだので、あなたは-isEqual:をオーバーライドする必要が

for(Manufacturer *manu in [fetchedResultsController fetchedObjects]) 
{ 
    id databaseIDTest = ^(Manufacturer * checkManu, NSUInteger idx, BOOL *stop){ 
     return [[checkManu objectID] isEqual:[manu objectID]]; 
    }; 

    if([manufacturers indexOfObjectPassingTest:databaseIDTest] == NSIndexNotFound) 
    { 
     NSLog(@"Deleting %@", manu.name); 
     [self.mContext deleteObject:manu]; 
    } 
} 

for(Manufacturer *manu in manufacturers) 
{ 
    id databaseIDTest = ^(Manufacturer * checkManu, NSUInteger idx, BOOL *stop){ 
     return [[checkManu objectID] isEqual:[manu objectID]]; 
    }; 
    NSArray * fetchedObjects = [fetchedResultsController fetchedObjects]; 
    if([fetchedObjects indexOfObjectPassingTest:databaseIDTest] == NSIndexNotFound) 
    { 
     NSLog(@"Adding %@", manu.name); 
     [newArray addObject:manu]; 
    } 
} 
+0

これは完全に真実ではありません。あなたは同じ文脈にあるので、2つのポインタ(メモリアドレス)を比較し、2つの管理対象オブジェクトIDを比較することは事実上同じことですが、2つのポインタを比較することは**ロット**安くなります。 –

+0

お返事ありがとうございますが、これはうまく動作していないようです...私の配列を手作業で繰り返し、発生数を数えなければならないかもしれないと考えてください。少なくともこれが、私がオブジェクトを「自分の方法」でテストするために考えることのできる唯一の方法です。 – Revoluzifer

-2

- (BOOL)isEqual:(id)other; 
{ 
    if (![other isKindOfClass:[Manufacturer class]]) { 
     return NO; 
    } 
    Manufacturer *otherManufacturer = other; 
    return ([self.name isEqual:otherManufacturer.name] && 
      ... 
      ); 
} 

はNSSet内部の封じ込めの確認は安いです(とパフォーマンスの問題に実行する場合、意味をなさない場合があります)。あなたは比較的まともな-hash実装を持っている場合にのみ動作しますが、それはこのように実装するのは簡単です:

- (NSUInteger)hash; 
{ 
    return [self.name hash] + [self.foo hash] + ...; 
} 

はわずか2つの使用し、ハッシュとトラフたくさんの悩みを行ってはいけない

- 可能性が最も高い3つの値をを使用してオブジェクトを一意に識別します。

+0

私は単に私のオブジェクトの比較メソッドをオーバーライドすることができますが、NSManagedObjectのサブクラスを使用しているので、私はできません。さもなければ、これは確かに最善の解決策でした;) – Revoluzifer

関連する問題