Pobieranie obiektu z Nssetu

Jeśli nie możesz pobrać obiektu za pomocą objectAtIndex: z Nssetu, to jak odzyskać obiekty?

Author: node ninja, 2010-09-30

8 answers

Istnieje kilka przypadków użycia zestawu. Można wyliczyć poprzez (np. z enumerateObjectsUsingBlock lub NSFastEnumeration), wywołanie containsObject aby przetestować członkostwo, użyj anyObject aby uzyskać element (nie przypadkowy), lub przekonwertować go na tablicę (w określonej kolejności) z allObjects.

Zestaw jest odpowiedni, gdy nie chcesz duplikatów, nie dbasz o porządek i chcesz szybkich testów członkostwa.

 134
Author: Matthew Flaschen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-30 03:18:22

NSSet nie posiada obiektu metody:

Spróbuj wywołać allObjects, które zwróci NSArray wszystkich obiektów.

 29
Author: No one in particular,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-30 00:12:52

Możliwe jest użycie filteredSetUsingPredicate, jeśli masz jakiś unikalny identyfikator, aby wybrać potrzebny obiekt.

Najpierw Utwórz predykat (zakładając, że Twój unikalny identyfikator w obiekcie nazywa się" identifier " i jest to NSString):

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

A następnie wybierz obiekt używając predykatu:

NSObject *myChosenObject = [mySet filteredSetUsingPredicate:myPredicate].anyObject;
 17
Author: Vitalii,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-04 14:20:01

NSArray *myArray = [myNSSet allObjects];

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

Zastąp NSUInteger indeksem żądanego obiektu.

 12
Author: krischu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-28 07:21:38

NSSet używa metody isEqual: (którą obiekty umieszczane w tym zestawie muszą przesłaniać dodatkowo metodę hash), aby określić, czy obiekt znajduje się wewnątrz niego.

Więc, na przykład, jeśli masz model danych, który definiuje jego unikalność przez wartość id (powiedzmy, że właściwość jest:

@property NSUInteger objectID;

Wtedy zaimplementowałbyś isEqual: as

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

I można zaimplementować hash:

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

Następnie możesz uzyskać obiekt o tym ID (a także sprawdzić, czy nie znajduje się w Nssecie) z:

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

Ale tak, jedynym sposobem, aby uzyskać coś z NSSet jest rozważenie tego, co określa jego wyjątkowość w pierwszej kolejności.

Nie testowałem tego, co jest szybsze, ale unikam używania wyliczeń, ponieważ może to być liniowe, podczas gdy użycie metody member: byłoby znacznie szybsze. Jest to jeden z powodów, dla których preferuje się użycie NSSet zamiast NSArray.

 6
Author: horseshoe7,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-19 20:32:47

Dla Swift3 & iOS10:

//your current set
let mySet : NSSet
//targetted index
let index : Int
//get object in set at index
let object = mySet.allObjects[index]
 5
Author: Kevin ABRIOUX,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-28 10:52:35
for (id currentElement in mySet)
{
    // ** some actions with currentElement 
}
 0
Author: Savchenko Dmitry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-20 21:31:25

Przez większość czasu nie zależy ci na zdobyciu jednego konkretnego obiektu z zestawu. Zależy ci na testowaniu, aby sprawdzić, czy zestaw zawiera obiekt. Do tego nadają się zestawy. Gdy chcesz sprawdzić, czy obiekt znajduje się w kolekcji, zestawy są znacznie szybsze niż tablice.

Jeśli nie zależy ci najaki przedmiot otrzymujesz, użyj -anyObject, który daje Ci tylko jeden przedmiot z zestawu, jak wkładanie ręki do torby i chwytanie czegoś.

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

Jeśli zależy ci na tym, jaki przedmiot get, użyj -member, które zwróci obiekt, lub nil, jeśli nie znajduje się w zestawie. Musisz mieć już obiekt, zanim go nazwiesz.

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

Oto kod, który możesz uruchomić w Xcode, aby zrozumieć więcej

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
Author: nevan king,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-09 13:13:46