简体   繁体   English

Objective c - NSMutableSet唯一对象属性

[英]Objective c - NSMutableSet unique object property

In my app I have a class Person with personId property. 在我的应用程序中,我有一个Person具有personId属性的类。
Now I need some data structure to hold a bunch of unique Person objects (unique = different personId) 现在我需要一些数据结构来保存一堆独特的Person对象(unique = different personId)

So I guess I should use NSMutableSet as my data structure, but how do I make the NSMutableSet compare the personId property when adding a person (so I won't add the same person more then ones)? 所以我想我应该使用NSMutableSet作为我的数据结构,但是如何让NSMutableSet在添加一个人时比较personId属性(所以我不会添加同一个人多一些)?

My goal is to have a collection of unique persons all the time (even if I add two persons with the same id), I want that the NSMutableSet will do all the hard work for me and if I'm adding a person that already exists it won't add it twice. 我的目标是始终拥有一组独特的人(即使我添加两个具有相同ID的人),我希望NSMutableSet能为我做所有艰苦的工作,如果我添加一个已经存在的人它不会添加两次。

You can achieve that by understanding how the comparison is made by the NSSet . 您可以通过了解NSSet如何进行比较来实现这一目标。 When you add a new object to the set, isEqual: method is called (it's an NSObject method) against each of the set's elements. 当你向集合中添加一个新对象时,对每个集合的元素调用isEqual:方法(它是一个NSObject方法)。 So what you can do is override this method and provide a custom comparison like this: 所以你可以做的是覆盖这个方法并提供这样的自定义比较:

NOTE: 注意:

If you override isEqual: method you must override hash method as well 如果重写isEqual:方法,则必须覆盖hash方法

// In your Person.m
- (BOOL)isEqual:(id)anObject
{
    return [self.personId isEqual:anObject.personId]; 
    // If it's an object. Otherwise use a simple comparison like self.personId == anObject.personId
}

- (NSUInteger)hash
{
    return self.personId; //Must be a unique unsigned integer
}

I think what you want is an NSMutableDictionary , mapping the personId to the Person object. 我想你想要的是一个NSMutableDictionary ,将personId映射到Person对象。

NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];

Person *person = something;
[dict setObject:personObj forKey:[NSNumber numberWithInt:[person personId]]];
... etc ...

(don't forget to release dict later somewhere). (不要忘记稍后在某处释放dict )。

In order to find the Person class for the specified personId (12, say), you can simply do: 为了找到指定personIdPerson类(比方说12),你可以简单地做:

Person *person = [dict objectForKey:[NSNumber numberWithInt:12]];

Note: that you have to store both the key and the value as objects (you cannot store primitive types). 注意:您必须将键和值都存储为对象(不能存储基本类型)。

You shouldn't need to worry about this when you're adding items to an array. 在向数组添加项目时,您不必担心这一点。 As long as you're adding a unique object each time, the properties of the object shouldn't matter. 只要您每次添加一个唯一对象,对象的属性就无关紧要了。

If you're worried about this and want to be doubly sure, use NSMutableSet instead (unless you need to maintain order of each object). 如果您对此感到担心并希望倍加确定,请改用NSMutableSet(除非您需要维护每个对象的顺序)。

Update 更新

You could use a predicate to check that an object with the same value does not exist before adding it. 您可以使用谓词检查在添加之前不存在具有相同值的对象。 This would work fine with both NSMutableArray and NSMutableSet. 这对NSMutableArray和NSMutableSet都可以正常工作。

//create array
NSMutableArray *array = [[NSMutableArray alloc] init];

//create person
Person *newPerson = [[Person alloc] init];

//add person
[array addObject:newPerson]

//check new object exists
if([[array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"personID == %@", [newPerson personID]]] count] == 0)
{
    //add object
    [array addObject:newPerson];
}

Very rough pseudocode but hopefully you get the gist :) 非常粗糙的伪代码,但希望你得到的要点:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM