从NSSet获取对象

时间:2010-09-30 00:07:18

标签: objective-c cocoa cocoa-touch object nsset

如果你无法从NSSet获取objectAtIndex的对象,那么如何检索对象呢?

8 个答案:

答案 0 :(得分:138)

一组有几个用例。您可以枚举(例如使用enumerateObjectsUsingBlock或NSFastEnumeration),调用containsObject来测试成员资格,使用anyObject来获取成员(非随机),或将其转换为数组(在没有特别的顺序)allObjects

如果您不想复制,不关心订单,并希望快速进行成员资格测试,那么这个集合是合适的。

答案 1 :(得分:30)

NSSet没有方法objectAtIndex:

尝试调用allObjects,它返回所有对象的NSArray。

答案 2 :(得分:17)

如果您有某种唯一标识符可以选择所需的对象,则可以使用filteredSetUsingPredicate。

首先创建谓词(假设对象中的唯一id被称为"标识符"它是一个NSString):

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

然后使用谓词选择对象:

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

答案 3 :(得分:13)

NSArray *myArray = [myNSSet allObjects];

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

将NSUInteger替换为所需对象的索引。

答案 4 :(得分:7)

对于Swift3& iOS10:

public void myScheduledTack(){
    myDate = getCurrentDate();

    myService.myMethod(myDate);
}
public getCurrentDate(){
 return new Date();
}

答案 5 :(得分:6)

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:方法会快得多。这是优先使用NSSet而不是NSArray的原因之一。

答案 6 :(得分:0)

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

答案 7 :(得分:0)

大多数时候,您都不关心从集合中获取一个特定对象。您关心测试以查看集合是否包含对象。这就是集合的优点。当您要查看对象是否在集合中时,集合要比数组快得多。

如果您不关心哪个对象,请使用-anyObject,它从集合中只给您一个对象,例如将您的手放在包中并抓住东西。 / p>

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

如果您关心要得到什么对象,请使用-member将对象退还给您,如果它不在集合中,则为nil。调用该对象之前,您必须已经拥有该对象。

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

您可以在Xcode中运行一些代码以了解更多信息

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);
}