it-swarm.com.de

Ein Objekt von einem NSSet abrufen

Wenn Sie mit objectAtIndex ein Objekt nicht von einem NSSet abrufen können, wie können Sie dann Objekte abrufen?

90
node ninja

Es gibt mehrere Anwendungsfälle für ein Set. Sie können durch (z. B. mit enumerateObjectsUsingBlock oder NSFastEnumeration) auflisten, containsObject aufrufen, um die Mitgliedschaft zu testen, verwenden Sie anyObject , um ein Mitglied zu erhalten (nicht zufällig) oder in ein Array (in keine bestimmte Reihenfolge) mit allObjects .

Ein Satz ist geeignet, wenn Sie keine Duplikate haben möchten, sich nicht um die Reihenfolge kümmern und schnelle Mitgliedschaftstests wünschen.

137

NSSet hat keine Methode objectAtIndex:

Versuchen Sie, allObjects aufzurufen, die ein NSArray aller Objekte zurückgibt.

30

wenn Sie über ein eindeutiges Bezeichner verfügen, können Sie gefiltertesSetUsingPredicate verwenden, um das gewünschte Objekt auszuwählen.

Erstellen Sie zuerst das Prädikat (vorausgesetzt, Ihre eindeutige ID im Objekt heißt "Bezeichner" und ist ein NSString):

NSPredicate *myPredicate = [NSPredicate predicateWithFormat:@"identifier == %@", identifier];

Wählen Sie dann das Objekt mithilfe des Prädikats aus:

NSObject *myChosenObject = [mySet filteredSetUsingPredicate:myPredicate].anyObject;
17
Vitalii

NSArray *myArray = [myNSSet allObjects];

MyObject *object = [myArray objectAtIndex:(NSUInteger *)]

ersetzen Sie NSUInteger durch den Index Ihres gewünschten Objekts.

13
krischu

Für Swift3 & iOS10:

//your current set
let mySet : NSSet
//targetted index
let index : Int
//get object in set at index
let object = mySet.allObjects[index]
7
Kevin ABRIOUX

NSSet verwendet die Methode isEqual: (die von den Objekten, die Sie in diese Gruppe einfügen, zusätzlich die Hash-Methode überschreiben muss), um festzustellen, ob sich ein Objekt darin befindet.

Wenn Sie beispielsweise über ein Datenmodell verfügen, das seine Eindeutigkeit anhand eines ID-Werts definiert (die Eigenschaft lautet:

@property NSUInteger objectID;

dann würden Sie isEqual: as implementieren

- (BOOL)isEqual:(id)object
{
  return (self.objectID == [object objectID]);
}

und Sie könnten Hash implementieren:

- (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
}

Anschließend können Sie ein Objekt mit dieser ID abrufen (und prüfen, ob es sich im NSSet befindet) mit:

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

Aber ja, der einzige Weg, etwas aus einem NSSet herauszuholen, besteht darin, das zu betrachten, was seine Einzigartigkeit überhaupt definiert.

Ich habe nicht getestet, was schneller ist, aber ich vermeide die Verwendung von Aufzählungen, da dies linear sein könnte, während die Methode member: viel schneller wäre. Dies ist einer der Gründe, warum NSSet anstelle von NSArray bevorzugt wird.

6
horseshoe7
for (id currentElement in mySet)
{
    // ** some actions with currentElement 
}
0

Meistens ist es Ihnen egal, ein bestimmtes Objekt aus einem Set zu erhalten. Sie möchten prüfen, ob ein Set ein Objekt enthält. Dafür sind Sets gut. Wenn Sie sehen möchten, ob sich ein Objekt in einer Auflistung befindet, sind Sets viel schneller als Arrays.

Wenn Sie sich nicht für das Objekt interessieren, das Sie erhalten, verwenden Sie -anyObject, wodurch Sie nur ein Objekt aus dem Set erhalten, z. B. eine Hand in eine Tasche stecken und etwas greifen.

Dog *aDog = [dogs anyObject]; // dogs is an NSSet of Dog objects

Wenn Sie sich für das Objekt interessieren, verwenden Sie -member, das Ihnen das Objekt zurückgibt, oder nil, wenn es sich nicht im Set befindet. Sie müssen das Objekt bereits haben, bevor Sie es aufrufen.

Dog *spot = [Dog dogWithName:@"Spot"];
// ...
Dog *aDog = [dogs member:spot]; // Returns the same object as above

Hier ist etwas Code, den Sie in Xcode ausführen können, um mehr zu verstehen

NSString *one = @"One";
NSString *two = @"Two";
NSString *three = @"Three";

NSSet *set = [NSSet setWithObjects:one, two, three, nil];

// Can't use Objective-C literals to create a set.
// Incompatible pointer types initializing 'NSSet *' with an expression of type 'NSArray *'
//  NSSet *set = @[one, two, three];

NSLog(@"Set: %@", set);
// Prints looking just like an array but is actually not in any order
//Set: {(
//     One,
//     Two,
//     Three
//     )}

// Get a random object
NSString *random = [set anyObject];
NSLog(@"Random: %@", random); // Random: One

// Iterate through objects. Again, although it prints in order, the order is a lie
for (NSString *aString in set) {
    NSLog(@"A String: %@", aString);
}

// Get an array from the set
NSArray *array = [set allObjects];
NSLog(@"Array: %@", array);

// Check for an object
if ([set containsObject:two]) {
    NSLog(@"Set contains two");
}

// Check whether a set contains an object and return that object if it does (nil if not)
NSString *aTwo = [set member:two];
if (aTwo) {
    NSLog(@"Set contains: %@", aTwo);
}
0
nevan king