IOS 的NSSet,NSHashMap,NSHashTable,NSPointerArray集合类

来源:互联网 发布:js动态添加tr td 编辑:程序博客网 时间:2024/05/18 01:38
  1. NSSet(NSMutableSet)集合的使用,和数组的区别是无序的,相同元素只留一份,这个和数学上的集合很相近
NSSet *set = [[NSSet alloc]initWithObjects:@"A",@"B", nil];    BOOL iscontent = [set containsObject:@"A"];    NSEnumerator *enumre = [set objectEnumerator];    NSString *str;    while (str=[enumre nextObject]) {        NSLog(@"%@",str);    }    NSArray *array1 = [[NSArray    alloc]initWithObjects:@"1",@"2",@"3",@"4", nil];    NSSet *set1 = [[NSSet alloc]initWithArray:array1];    array1 = [set1 allObjects];    NSMutableSet *muset = [[NSMutableSet alloc]init];    [muset addObject:@"m1"];    //添加元素有重复的实际上只添加了一个    [muset addObject:@"m2"];    [muset removeObject:@"m1"];    [muset removeAllObjects];    //将两个集合合并,重复元素只留一个    [muset unionSet:set1];    //删除重复元素    [muset minusSet:set1];    NSIndexSet *indexset = [[NSIndexSet alloc]initWithIndexesInRange:NSMakeRange(1, 3)];    NSArray *arr12 = [[NSArray array]initWithObjects:@"1",@"1",@"1",@"1",@"1",@"1",@"1",@"1", nil];    NSArray *subarr = [arr12 objectsAtIndexes:indexset];    NSMutableIndexSet *muindexset = [[NSMutableIndexSet alloc]init];    [muindexset addIndex:0];    [muindexset addIndex:2];    subarr = [arr12 objectsAtIndexes:muindexset];
  1. NSHashTable效仿了NSSet(NSMutableSet),但提供了比NSSet更多的操作选项,尤其是在对弱引用关系的支持上,NSHashTable在对象/内存处理时更加的灵活。相较于NSSet,NSHashTable具有以下特性:

NSSet(NSMutableSet)持有其元素的强引用,同时这些元素是使用hash值及isEqual:方法来做hash检测及判断是否相等的。
NSHashTable是可变的,它没有不可变版本。
它可以持有元素的弱引用,而且在对象被销毁后能正确地将其移除。而这一点在NSSet是做不到的。
它的成员可以在添加时被拷贝。
它的成员可以使用指针来标识是否相等及做hash检测。
它可以包含任意指针,其成员没有限制为对象。我们可以配置一个NSHashTable实例来操作任意的指针,而不仅仅是对象。
初始化NSHashTable时,我们可以设置一个初始选项,这个选项确定了这个NSHashTable对象后面所有的行为。这个选项是由NSHashTableOptions枚举来定义的

//个人认为NSHashTable吸引人的地方在于可以持有元素的弱引用,而且在对象被销毁后能正确地将其移除。比如下面的弱引用添加到数组中

-(instancetype)init{    if (self=[super init]) {        [self test1];    }    NSLog(@"%lu",(unsigned long)_hashtable.count);    return self;}-(void)test1{    if (!_hashtable) {         _hashtable = [NSHashTable weakObjectsHashTable];    }    NSObject *obj = [NSObject new];    __weak NSObject *obj1 =obj;    [_hashtable addObject:obj1];}

NSHashTable似乎比NSSet(NSMutableSet)要好啊。那是不是我们就应用都使用NSHashTable呢?在添加对象的操作中,NSHashTable所有的时间差不多是NSMutableSet的2倍,而在其它操作中,性能大体相近。所以,如果我们只需要NSSet的特性,就尽量用NSSet。

  1. NSMapTable对于NSDictionary来说,有几点特别的地方,其中表现在它可以指定key/value是需要strong,weak,甚至是copy,如果使用的是weak,当key、value在被释放的时候,会自动从NSMapTable中移除这一项,这一点和NSHashTable很像。NSMapTable中可以包含任意指针,使用指针去做检查操作。

    NSMapTable与NSDictionary

接下来我们针对上面提出的几点优点,做一下浅析:

NSDcitionary有一个可变的类型即NSMutableDictionary,然而NSMapTable没有另外一个可变类,因为它本身就是可变的
NSDcitionary或者NSMutableDictionary中对于key和value的内存管理是,对key进行copy,对value进行强引用。

NSMapTable是需要key支持NSCopying协议,并且在NSDictionary中,object是由“key”来索引的,key的值不能改变,为了保证这个特性在NSDcitionary中对key的内存管理为copy,在复制的时候需要考虑对系统的负担,因此key应该是轻量级的,所以通常我们都用字符串和数字来做索引,但这只能说是key-to-object映射,不能说是object-to-object的映射。
NSMapTabTable更适合于我们一般所说的映射标准,它既可以处理key-to-value又可以处理object-to-object

NSMapTable(顾名思义)更适合于一般意义的映射。这取决于它是如何构造的,NSMapTable可以处理的“key-to-object”样式映射的NSDictionary,但它也可以处理“object-to-object”的映射 - 也被称为“associative array”或简称为“map”。

NSMapTable *keyToObjectMapping =[NSMapTable        mapTableWithKeyOptions:NSMapTableCopyIn        valueOptions:NSMapTableStrongMemory];

将会和NSMutableDictionary工作得一样一样的,复制其“key”,并retaining它的“object”。

一个纯粹的对象到对象(object-to-object)的映射可以构造如下:

NSMapTable *objectToObjectMapping =    [NSMapTable mapTableWithStrongToStrongObjects];

一个对象到对象(object-to-object)的行为可能以前可以用NSDictionary来模拟,如果所有的key都是一个NSNumber包含于该映射的源对象的内存地址(不要笑,我见过这种情况),但这些内存地址都是奔波在外,Cocoa中首次提供了一个真正的对象到对象的映射NSMapTable。
NSMapTable提供的选项是由三部分组成:一个“memory option”(内存选项),一个“personality option”和“copy in”标志。你可以为每个部分使用一个选项(如果没有提供一个选项的部分将会使用默认行为),这个部分都是位标志(bit flag)(二进制 “or” 合并在一起)。

理论上,NSMapTable允许以下选项:

NSMapTableStrongMemory (a “memory option”)
NSMapTableWeakMemory (a “memory option”)
NSMapTableObjectPointerPersonality (a “personality option”)
NSMapTableCopyIn (a “copy option”)

NSMapTableStrongMemory是默认的“memory option”。然而,默认的“personality option”,默认“copy in”的行为没有名字那么这两个值可以被视为隐含在列表中。

memory option
Objective-C使用“strong”和“week”作为垃圾回收机制相关的术语,它可能不是很明显,这些选项可以在垃圾回收机制代码之外使用(苹果称它为手动内存管理)。

在垃圾回收机制外,他们被定义为:

strong: 使用 retain 和 release
weak: 不使用 retain 和 release
NSMapTable只允许NSPointerFunctionsOptions对应的Objective-C对象“personality option”。还有其他NSPointerFunctionsOptions “personality option”里的“strong”指针的行为不包括retain和release,但这些选项在NSMapTable都是不允许的。

  1. NSPointerArray的用处 : 也许你对NSArray使用了如指掌,每个加入到NSArry的对象都会被NSArray持有.有时候,这种特性不是我们想要的结果. 有时候,我们想将对象存储起来,但是不想让数组增加了这个对象的引用计数,这个时候,NSPointArray才是你想要的.
NSPointerArray *pointarr = [NSPointerArray weakObjectsPointerArray];    NSObject *obj = [NSObject new];    [pointarr addPointer:(__bridge void * _Nullable)(obj)];
1 0
原创粉丝点击