NSSet から objectAtIndex: でオブジェクトを取得できない場合、どのようにオブジェクトを取得しますか?
8 に答える
セットにはいくつかのユースケースがあります。列挙 (enumerateObjectsUsingBlock
または NSFastEnumeration など)、containsObject
メンバーシップのテストの呼び出しanyObject
、メンバーの取得 (ランダムではない) の使用、または を使用した配列への変換 (順不同) が可能allObjects
です。
セットは、重複を避け、順序を気にせず、迅速なメンバーシップ テストが必要な場合に適しています。
NSSet にはメソッド objectAtIndex がありません:
すべてのオブジェクトの NSArray を返す allObjects を呼び出してみてください。
必要なオブジェクトを選択するための何らかの一意の識別子がある場合は、filteredSetUsingPredicate を使用できます。
最初に述語を作成します (オブジェクト内の一意の ID が「識別子」と呼ばれ、NSString であると仮定します):
NSPredicate *myPredicate = [NSPredicate predicateWithFormat:@"identifier == %@", identifier];
次に、述語を使用してオブジェクトを選択します。
NSObject *myChosenObject = [mySet filteredSetUsingPredicate:myPredicate].anyObject;
NSArray *myArray = [myNSSet allObjects];
MyObject *object = [myArray objectAtIndex:(NSUInteger *)]
NSUInteger を目的のオブジェクトのインデックスに置き換えます。
NSSet はメソッド isEqual: (そのセットに入れるオブジェクトは、さらにハッシュ メソッドをオーバーライドする必要があります) を使用して、オブジェクトがその中にあるかどうかを判断します。
たとえば、一意性を id 値で定義するデータ モデルがあるとします (プロパティは次のようになります。
@property NSUInteger objectID;
次に、 isEqual: as を実装します
- (BOOL)isEqual:(id)object
{
return (self.objectID == [object objectID]);
}
ハッシュを実装できます:
- (NSUInteger)hash
{
return self.objectID; // to be honest, I just do what Apple tells me to here
// because I've forgotten how Sets are implemented under the hood
}
次に、その ID を持つオブジェクトを取得できます (NSSet にあるかどうかを確認するだけでなく)。
MyObject *testObject = [[MyObject alloc] init];
testObject.objectID = 5; // for example.
// I presume your object has more properties which you don't need to set here
// because it's objectID that defines uniqueness (see isEqual: above)
MyObject *existingObject = [mySet member: testObject];
// now you've either got it or existingObject is nil
しかし、そうです、NSSet から何かを取得する唯一の方法は、そもそもその一意性を定義するものを考慮することです。
何が速いかはテストしていませんが、列挙型は線形である可能性があるため、列挙型の使用は避けていますが、 member: メソッドを使用するとはるかに高速になります。これが、NSArray ではなく NSSet の使用を好む理由の 1 つです。