zoukankan      html  css  js  c++  java
  • iOS-相关集合类

    第一:NSArrary

    1.1:集合的基本方法

      1.创建集合
       NSArray 是不可变数组,一旦创建完成就不能够对数组进行,添加,删除等操作

    NSArray * array = [[NSArray alloc] init];

     2.通过构造方法的方式创建一个NSArray

    //在创建一个NSArray的时候,集合的最后一个元素一定是nil,判断nil决定集合的结尾
    NSArray * array1 = [NSArray arrayWithObjects:@"one",@"two",@"three", nil];
    NSArray * array2 = [[NSArray alloc] initWithObjects:@"one",@"two",number, nil];
    NSArray * karray = @[@"a",@"b",@"c"];
    NSString * kstr = karray[0];//访问元素位置
    //数组的index时从0开始的
    NSString * str = [array objectAtIndex:0];
    NSLog(@"str %@",str);
    //获得数组的元素个数
    NSUInteger arrayCount = [array count];
    // 判断数组中是否存在某个对象
    BOOL isContain = [array containsObject:id]; 

    特性:
    1.数组中可以存储不同类型的对象
    2.数组实际上存储的时对象的地址,同样也可以存储数组的地址
    3.存储自定义的对象 (最好都给我重写 description方法)
    4.数组中存储基本数据类型, (如果你要在数组中存储基本数据类型,请包装好了之后再去存 NSNumber)
    5.注意不要把nil值存储到NSArray中,会导致数据丢失

    1.2:数组排序:

    1.使用sortedArrayUsingSelector

    NSArray * array = @[@"b",@"d",@"a",@"z"];
    array = [array sortedArrayUsingSelector:@selector(compare:)]; //系统自带

    2.使用block方式排序
    a. 降序

    NSArray *tMlist = @[@4,@5,@2,@6,@3,@7,@8];
    //降序序8,7,。。
    NSArray *tArray = [tMlist sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2)
    {
    NSNumber *tNumber1 = (NSNumber *)obj1;
    NSNumber *tNumber2 = (NSNumber *)obj2;
    //因为不满足sortedArrayUsingComparator方法的默认排序顺序,则需要交换
    if ([tNumber1 integerValue] < [tNumber2 integerValue])
    return NSOrderedDescending;
    return NSOrderedAscending;
    //因为满足sortedArrayUsingComparator方法的默认排序顺序,则不需要交换
    if ([tNumber1 integerValue] > [tNumber2 integerValue])
    return NSOrderedAscending;
    return NSOrderedDescending;

    b 升序
    NSArray *tMlist = @[@4,@5,@2,@6,@3,@7,@8];
    //结果:升序2,4,。。
    NSArray *tArray = [tMlist sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2)
    {
    NSNumber *tNumber1 = (NSNumber *)obj1;
    NSNumber *tNumber2 = (NSNumber *)obj2;
    //因为满足sortedArrayUsingComparator方法的默认排序顺序,则不需要交换
    if ([tNumber1 integerValue] < [tNumber2 integerValue])
    return NSOrderedAscending;
    return NSOrderedDescending;
    // 因为不满足sortedArrayUsingComparator方法的默认排序顺序,则需要交换。
    // if ([tNumber1 integerValue] < [tNumber2 integerValue])
    // return NSOrderedAscending ;
    // return NSOrderedDescending;
    }]; 
    
    c 数组逆转
    NSArray *tMlist = @[@4,@5,@2,@6,@3,@7,@8];
    NSArray *tArray = [tMlist sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2)
    {
    NSNumber *tNumber1 = (NSNumber *)obj1;
    NSNumber *tNumber2 = (NSNumber *)obj2;
    
    //数组逆转
    return NSOrderedDescending;
    }];
    d.数组不变
    NSArray *tMlist = @[@4,@5,@2,@6,@3,@7,@8];
    NSArray *tArray = [tMlist sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2)
    {
    NSNumber *tNumber1 = (NSNumber *)obj1;
    NSNumber *tNumber2 = (NSNumber *)obj2;
    //数组不变
    return NSOrderedAscending;
    }];

    总结:

    1.sortedArrayUsingComparator这个方法本身就是按递增的方式排序。
    2.返回的返回值(NSOrderedAscending 不交换,NSOrderedSame 不交换,NSOrderedDescending 交换)。
    例如:object1 < object2 返回:NSOrderedDescending 则交换(变为object2,object1),以保证安方法本身升序。返回NSOrderedAscending,两者不交换。

    对于Comparator的返回值文档有下面的说明

    NSOrderedAscending
    The left operand is smaller than the right operand.
    NSOrderedSame
    The two operands are equal.
    NSOrderedDescending
    The left operand is greater than the right operand
    如果你期望的是值小的在前而值大的在后(升序),则可以在比较的时候返回NSOrderedAscending(-1),否则,就是NSOrderedDescending(1)。

    3.使用自定义对象排序 :如果你向给你自己定义的对象排序,必须根据某一个属性来排序,

    //sortDescriptorWithKey 参数要的就是你对象中,要依据哪个属性来排序,你就把哪个属性的名字当成key传入
    //ascending YES表示正序 NO表示倒叙
      NSSortDescriptor * d1 = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:NO];
      NSSortDescriptor * d2 = [NSSortDescriptor sortDescriptorWithKey:@"year" ascending:NO];
    
    //如果你要使用多个属性进行排序,默认在前面的NSSortDescriptor优先级比较高
      NSArray * descripts = @[d2,d1];
      array3 = [array3 sortedArrayUsingDescriptors:descripts]; 

    1.3:遍历数组

    遍历数组的三种方式

    1>普通方式:

    for (int i = 0; i<array1.count; i++){
     if (i ==0)
        break;
    }

    2>将array1数组中的每个对象拿出来赋给obj然后依次打印

    for (id obj in array1){
    // id obj 代表数组中的对象
    // 获取obj对象在数组中的索引
    NSUInteger index = [array1 indexOfObject:obj];
    NSLog(@"%ld--%@",index,obj);
    }

    3>使用Block 每次从数组中遍历一个元素后就传递给block,block也相应的执行一次

    // block中的id obj对应数组中的元素,NSUInteger idx对应数组中元素的索引 BOOL用来停止遍历
    [array1 enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop){
    NSLog(@"%ld--%@",idx,obj);
    // 如果索引为0 立即停止遍历
    if (idx ==0){
    * stop = YES;
    }
    }; 

    1.4:可变数组:

    1.创建可变数组

    NSMutableArray * array = [[NSMutableArray alloc] initWithCapacity:0];

    2.数组中加入元素

    [array addObject:str1];

    3.指定对象插入的位置

    [array insertObject:str1 atIndex:2];

    4.删除 会通过对象,删除数组中所有的同一个地址的对象

    [array removeObject:str1];

    4.通过索引的方式删除对象,超出了数组的count值,那么就会导致异常 index beyond bounds

    [array removeObjectAtIndex:0];
    [array addObject:str2];
    [array addObject:str3];
    [array addObject:str1];

    5.删除数组中所有的元素

    [array removeAllObjects]; 

    第二:NSDictionary

    第一:NSDictionary
    字典是以键值对的形式来存储数据 key value
    字典的顺序不是按照存储时候的顺序。
    字典中可以存任意数据类型

    1.创建字典

    NSDictionary *dic1 = [NSDictionary dictionaryWithObject:@"value" forKey:@"key"]; 

    2.创建多个元素字典

    NSDictionary *dic2 = [NSDictionary dictionaryWithObjectsAndKeys: 
    @"value1", @"key1", 
    @"value2", @"key2", 
    @"value3", @"key3", 
    @"value4", @"key4", 
    nil];

    3.根据现有的字典创建字典

    NSDictionary *dic3 = [NSDictionary dictionaryWithDictionary:dic2];

    4.根据key获取value

     [dic3 objectForKey:@"key3"]);

    5.获取字典数量

    NSLog(@"dic count :%d", dic3.count); 

    6.所有的键集合

    NSArray *keys = [dic3 allKeys]; 

    7.所有值集合

    NSArray *values = [dic3 allValues]; 
    

     1.2 可变字典

       1.创建可变字典

    NSMutableDictionary *mutableDic = [[NSMutableDictionary alloc] initWithObjectsAndKeys: 
    @"mvalue1", @"mkey1", 
    @"mvalue2", @"mkey2", nil]; 

       2.添加现有的字典数据

    [mutableDic addEntriesFromDictionary:dic3]; 

    3.添加新的键值对象

    [mutableDic setValue:@"set1" forKey:@"setKey1"]; 

    4.以新的字典数据覆盖旧的字典数据

    [mutableDic setDictionary:dic2]; 

    5.根据key删除value

    [mutableDic removeObjectForKey:@"key1"]; 

    1.3 遍历方法
      1.快速遍历

    for(id key in mutableDic) { 
    NSLog(@"key :%@ value :%@", key, [mutableDic objectForKey:key]); 
    } 

      2.枚举遍历

    NSEnumerator *enumerator = [mutableDic keyEnumerator]; 
    id key = [enumerator nextObject]; 
    while (key) { 
    NSLog(@"enumerator :%@", [mutableDic objectForKey:key]); 
    key = [enumerator nextObject]; 
    } 

    3.根据key数组删除元素

    [mutableDic removeObjectsForKeys:keys]; 

    4.删除所有元素

    [mutableDic removeAllObjects]; 

    第三:NSSet 集合

    1> NSSet是一组单值对象的不可变集合,集合中元素没有顺序;

    2> 操作包括:搜索、添加、删除集合中的元素(仅用于可变集合)、比较两个集合,计算两个集合的交集和并集等。

    3> 获取元素个数:集合名.count
    1.1、NSSet集合常用方法(部分)
      1.构造方法

    + (instancetype)setWithObjects:obj1, obj2, ..., nil;

     2.使用一系列对象初始化新分配的集合:

    - (instancetype)initWithObjects:(const id [])objects count:(NSUInteger)cnt; 

    3.确定集合是否包含anObject对象:

    - (BOOL)containsObject:(id)anObject;

    4.使用member:访问集合中的某一对象,有就返回此元素,没有就返回null:

    - (id)member:(id)object;

    5.为集合中的所有对象返回一个NSEnumerato对象:

    - (NSEnumerator *)objectEnumerator;
    

     6.确定receiver的每个元素是否都出现在otherSet中:

    - (BOOL)isSubsetOfSet:(NSSet *)otherSet; 

    7.确定是否receiver中至少一个元素出现在对象otherSet中:

    - (BOOL)intersectsSet:(NSSet *)otherSet;

    8.确定两个集合是否相等:

    - (BOOL)isEqualToSet:(NSSet *)otherSet;

    1.2,NSMutableSet

          NSMutableSet是NSSet的子类,是可变集合;

     常用方法(部分):

    1.创建新集合,使其具有存储numItems个元素的初始空间:

    + (instancetype)setWithCapacity:(NSUInteger)numItems;

    2.将新分配的集合设置为numItems个元素的存储空间:

    - (instancetype)initWithCapacity:(NSUInteger)numItems;

    3.将对象object添加到集合中:

    - (void)addObject:(id)object;

    4.从集合中删除对象:

    - (void)removeObject:(id)object;

    5.删除集合中所有对象:

    - (void)removeAllObjects;

    6.将对象otherSet的所有元素添加到接收者:

    - (void)unionSet:(NSSet *)otherSet;

    7.从接收者中删除otherSet的左右元素:

    - (void)minusSet:(NSSet *)otherSet;

    8.从接受者中的所有不属于otherSet的元素删除:

    - (void)intersectSet:(NSSet *)otherSet;

    第四:集合的相互转换

    //1.NSArray 转换成 NSMutableArray
    NSArray * array = @[@"one",@"two",@"three"];
    NSMutableArray * muArray = [NSMutableArray arrayWithArray:array];
    NSLog(@"muarray %@",muArray);
     //2.NSDictonary 转换成 NSMutableDictionary
    NSDictionary * dic = @{@"one":@"1",@"two":@"2"};
    NSMutableDictionary * muDic = [NSMutableDictionary dictionaryWithDictionary:dic];
    NSLog(@"mudic %@ ",muDic);
     //3.NSset 转换成 NSMutableSet
    NSSet * set = [[NSSet alloc] initWithObjects:@"one",@"two", nil];
    NSMutableSet *muSet = [NSMutableSet setWithSet:set];
    NSLog(@"muSet %@",muSet);
    //4.NSArray 转换成NSSet
    NSMutableSet * muSet2 = [NSMutableSet setWithArray:array];
    NSLog(@"muSet2 %@",muSet2);
     //5.NSDictionary 转化成NSArray
    NSArray * allkeys = [dic allKeys];
    NSLog(@"allkeys %@",allkeys);
    NSArray * allValues = [dic allValues];
    NSLog(@"allValues %@",allValues);
     //6.字符串转换成数组 
    NSString * str = @"www.itacast.cn"; 
    NSArray * strArray =[str componentsSeparatedByString:@"."];
    NSLog(@"strArray %@",strArray); 

    第五:NSPointerArray

    NSArray的弱引用版本,也可以存储非oc对象,对应着 NSArray,添加元素操作很慢。 

    1.1,与NSArray的异同    

     * 相同点:

          1.用于有序的插入或移除;

          2.遵循 NSFastEnumeration ,可以通过 for...in 来进行遍历。

     * 不同点:

       1. 可以存储 NULL,并且 NULL 还参与 count 的计算;

       2. count 可以 set,如果直接 set count,那么会使用 NULL 占位;

       3.可以存储 weak 来修饰成员;

       4.成员可以是所有指针类型;


    1.2,初始化

    NSPointerArray 与 NSMutableArray 很像,都是可变有序集合。最大的不同就是它们的初始化方法,
    NSPointerArray
      1.初始化方法:

    - (instancetype)initWithOptions:(NSPointerFunctionsOptions)options;
    - (instancetype)initWithPointerFunctions:(NSPointerFunctions *)functions; 

      2.类方法:

    + (NSPointerArray *)pointerArrayWithOptions:(NSPointerFunctionsOptions)options;
    + (NSPointerArray *)pointerArrayWithPointerFunctions:(NSPointerFunctions *)functions;

    枚举:NSPointerFunctionsOptions
      主要分为三大类:

       * 内存管理
         NSPointerFunctionsStrongMemory :缺省值,在 CG 和 MRC 下强引用成员
         NSPointerFunctionsZeroingWeakMemory :已废弃,在 GC 下,弱引用指针,防止悬挂指针
         NSPointerFunctionsMallocMemory 与 NSPointerFunctionsMachVirtualMemory : 用于 Mach 的虚拟内存管理
         NSPointerFunctionsWeakMemory :在 CG 或者 ARC 下,弱引用成员
       * 特性,用于标明对象判等方式
         NSPointerFunctionsObjectPersonality : hash 、 isEqual 、对象描述
         NSPointerFunctionsOpaquePersonality :pointer 的 hash 、直接判等
         NSPointerFunctionsObjectPointerPersonality :pointer 的 hash 、直接判等、对象描述
         NSPointerFunctionsCStringPersonality :string 的 hash 、 strcmp 函数、UTF-8 编码方式的描述
         NSPointerFunctionsStructPersonality :内存 hash 、 memcmp 函数
         NSPointerFunctionsIntegerPersonality :值的 hash
       * 内存标识
         NSPointerFunctionsCopyIn :根据第二类的选择,来具体处理。
         如果是 NSPointerFunctionsObjectPersonality ,则根据 NSCopying 来拷贝。
    所以在使用时,可以多个组合,
     比如:需要强引用成员、使用对象方式对比、并且 add 时 copy 对象:

    NSPointerFunctionsOptions *options = NSPointerFunctionsStrongMemory | NSPointerFunctionsObjectPersonality | NSPointerFunctionsCopyIn;
    NSPointerFunctions
         3.添加pointer(NULL也能添加)

    - (void)addPointer:(nullable void *)pointer;  // add pointer at index 'count' 

         4.通过索引的方式删除pointer

    - (void)removePointerAtIndex:(NSUInteger)index;    // everything above index, including holes, slide lower
    

         5.通过索引的方式添加Pointer   

    - (void)insertPointer:(nullable void *)item atIndex:(NSUInteger)index;  // everything at & above index, including holes, slide higher
    

         6.通过索引的方式替换对应Pointer

    - (void)replacePointerAtIndex:(NSUInteger)index withPointer:(nullable void *)item;  //  NULL item is okay; index must be < count

          7.剔除集合中为 NULL 的成员

    - (void)compact;   // eliminate NULLs
    

    注意:
      当我们主动给 NSPointerArray 添加 NULL 时,数组会标记有空元素插入,此时 compact 函数才会生效,也就是说, compact 函数会先判断是否有标记,之后才会剔除。 

    第六:NSMapTable

    对应NSDictionary的弱引用版本,添加元素和存取操作都比NSMutableDictionary慢点。
    除了 集合的共有特点以外,比起传统字典,它还有一些优势:

    key 可以不用遵循 NSCopying 协议;
    key 和 value 的内存管理方式可以分开,如:key 是强引用,value 是弱引用;
    相比起 NSPointerArray , NSMapTable 的初始化方法要多得多:

      1.实例方法,虽然有 capacity 参数,但实际没用到

    - (instancetype)initWithKeyOptions:(NSPointerFunctionsOptions)keyOptions valueOptions:(NSPointerFunctionsOptions)valueOptions capacity:(NSUInteger)initialCapacity;
    - (instancetype)initWithKeyPointerFunctions:(NSPointerFunctions *)keyFunctions valuePointerFunctions:(NSPointerFunctions *)valueFunctions capacity:(NSUInteger)initialCapacity;

      2.便利构造器

    + (NSMapTable<KeyType, ObjectType> *)mapTableWithKeyOptions:(NSPointerFunctionsOptions)keyOptions valueOptions:(NSPointerFunctionsOptions)valueOptions;

      3.返回指定 key、value 内存管理类型的 map

    + (NSMapTable<KeyType, ObjectType> *)strongToStrongObjectsMapTable NS_AVAILABLE(10_8, 6_0);
    + (NSMapTable<KeyType, ObjectType> *)weakToStrongObjectsMapTable NS_AVAILABLE(10_8, 6_0);
    + (NSMapTable<KeyType, ObjectType> *)strongToWeakObjectsMapTable NS_AVAILABLE(10_8, 6_0);
    + (NSMapTable<KeyType, ObjectType> *)weakToWeakObjectsMapTable NS_AVAILABLE(10_8, 6_0);

    其实,这么多的初始化方法就对应着四种搭配:

      key 为 strong,value 为 strong
      key 为 strong,value 为 weak
      key 为 weak,value 为 strong
      key 为 weak,value 为 weak

    当用 weak 修饰 key 或 value 时,有一方被释放,则该键值对移除。

       4. NSMapTable可以使用的函数

    FOUNDATION_EXPORT void NSFreeMapTable(NSMapTable *table);
    FOUNDATION_EXPORT void NSResetMapTable(NSMapTable *table);
    FOUNDATION_EXPORT BOOL NSCompareMapTables(NSMapTable *table1, NSMapTable *table2);
    FOUNDATION_EXPORT NSMapTable *NSCopyMapTableWithZone(NSMapTable *table, NSZone *zone);
    FOUNDATION_EXPORT BOOL NSMapMember(NSMapTable *table, const void *key, void **originalKey, void **value);
    FOUNDATION_EXPORT void *NSMapGet(NSMapTable *table, const void *key);
    FOUNDATION_EXPORT void NSMapInsert(NSMapTable *table, const void *key, const void *value);
    FOUNDATION_EXPORT void NSMapInsertKnownAbsent(NSMapTable *table, const void *key, const void *value);
    FOUNDATION_EXPORT void *NSMapInsertIfAbsent(NSMapTable *table, const void *key, const void *value);
    FOUNDATION_EXPORT void NSMapRemove(NSMapTable *table, const void *key);
    FOUNDATION_EXPORT NSMapEnumerator NSEnumerateMapTable(NSMapTable *table);
    FOUNDATION_EXPORT BOOL NSNextMapEnumeratorPair(NSMapEnumerator *enumerator, void **key, void **value);
    FOUNDATION_EXPORT void NSEndMapTableEnumeration(NSMapEnumerator *enumerator);
    FOUNDATION_EXPORT NSUInteger NSCountMapTable(NSMapTable *table);
    FOUNDATION_EXPORT NSString *NSStringFromMapTable(NSMapTable *table);
    FOUNDATION_EXPORT NSArray *NSAllMapTableKeys(NSMapTable *table);
    FOUNDATION_EXPORT NSArray *NSAllMapTableValues(NSMapTable *table);

    第七:NSHashTable

        可以包含弱引用对象的set集合,通常使用weakObjectsHashTable构造函数 ,它的 API 更为简单,与 NSMapTable 同样,初始化方法的 capacity 并未生效。

    - (instancetype)initWithOptions:(NSPointerFunctionsOptions)options capacity:(NSUInteger)initialCapacity;
    - (instancetype)initWithPointerFunctions:(NSPointerFunctions *)functions capacity:(NSUInteger)initialCapacity;

        值得注意的是, NSHashTable 有一个 allObjectes 的属性,返回 NSArray ,即使 NSHashTable 是弱引用成员, allObjects 依然会对成员进行强引用。

    typedef struct {NSUInteger _pi; NSUInteger _si; void *_bs;} NSHashEnumerator;
    FOUNDATION_EXPORT void NSFreeHashTable(NSHashTable *table);
    FOUNDATION_EXPORT void NSResetHashTable(NSHashTable *table);
    FOUNDATION_EXPORT BOOL NSCompareHashTables(NSHashTable *table1, NSHashTable *table2);
    FOUNDATION_EXPORT NSHashTable *NSCopyHashTableWithZone(NSHashTable *table, NSZone *zone);
    FOUNDATION_EXPORT void *NSHashGet(NSHashTable *table, const void *pointer);
    FOUNDATION_EXPORT void NSHashInsert(NSHashTable *table, const void *pointer);
    FOUNDATION_EXPORT void NSHashInsertKnownAbsent(NSHashTable *table, const void *pointer);
    FOUNDATION_EXPORT void *NSHashInsertIfAbsent(NSHashTable *table, const void *pointer);
    FOUNDATION_EXPORT void NSHashRemove(NSHashTable *table, const void *pointer);
    FOUNDATION_EXPORT NSHashEnumerator NSEnumerateHashTable(NSHashTable *table);
    FOUNDATION_EXPORT void *NSNextHashEnumeratorItem(NSHashEnumerator *enumerator);
    FOUNDATION_EXPORT void NSEndHashTableEnumeration(NSHashEnumerator *enumerator);
    FOUNDATION_EXPORT NSUInteger NSCountHashTable(NSHashTable *table);
    FOUNDATION_EXPORT NSString *NSStringFromHashTable(NSHashTable *table);
    FOUNDATION_EXPORT NSArray *NSAllHashTableObjects(NSHashTable *table);

    第八:小结

    这NSPointerArray,NSMapTable,NSHashTable类集合类型在 10.5 之后引入,比传统的集合类型更为强大,但是它们的方法却没有传统集合类型多,比如对于 NSPointerArray 来说:

    * 操作均基于 index,无法通过 object 来进行操作;
    * 无法直接插入 array,或用 array 初始化;
    * 查找功能没有 NSArray 强大;
    * 没有逆序、排序等 API 提供
    以上几点仅仅是举的例子,所以 NSPointerArray 也并没有看起来的那么强大,一切选择标准,都应该依据具体需求。

  • 相关阅读:
    Qt学习之路,part1
    1.获取状态栏的高度
    如何在Android Studio中上传代码到Gitee上
    关于类图
    外观模式
    关于类的实例
    SharedPreference中关于editor.apply()和editor.commit()
    活动的4种启动模式
    unittest中case批量管理
    unittest使用
  • 原文地址:https://www.cnblogs.com/lxlx1798/p/6601220.html
Copyright © 2011-2022 走看看