IOS集合

IOS中用于存储数据对象有3个类别:数组、字典和集合,这3个Foundation集合都是高效的并且被OSX和IOS共享

Art/collections_intro_2x.png

集合有着一些共性,都是对象的持有(包括可变和不可变对象)

常见的操作:枚举、判断是否持有一个对象、访问不存在对象

可变的集合还有动态添加和删除对对象的持有

尽管他们之间有着某些共性,但是对他们的如何使用决定了他们本身的表现。

数组(NSArray NSMutableArray):

当对于元素的顺序很重要的时候我们应该用数组存储,例如表视图。

数组是一个有序的集合,它可以包含一个猫、也可以包含一个狗,他所包含的类别不必须是一样的(因为它里面没有对元素进行泛型化以及元素是NSObject的子类即可,即无法存储基本数据类型,除非进行装箱)





数组的基础知识
NSArray是不变数组,一旦创建不可对其进行添加元素、删除元素和替换元素。但是你可以对元素本身进行修改(元素本身支持修改)。集合的可变性不会影响到其内部元素的可变性(类似于C++中的const,关键在于Const修饰谁),如果元素很少改变或不改变应该使用不可变集合。

NSMutableArray可以做NSArray上支持的所有操作,除此之外还可以对其本身进行添加、修改和替换元素。当其本身改变很大我们应该用可变数组,当然大型数组初始化会需要更多时间。

我们可以用数组来初始化数组,arrayWithArray,这里进行的是mutable拷贝,即使你用NSArray的实例,那么也会对元素内部的数据进行mutalble拷贝。

集合的深复制与浅复制,具体请参见我的另一篇博客,OC中的深复制和浅复制



注:数组花费常量时间在访问一个元素,删除最后一个元素和在最后添加一个元素和替换一个元素,花费线性时间在中间位置插入一个元素
在数组中搜索元素:
indexOfObject用的是isEqual方法,indexOfObjectIdenticalTo比较的是指针地址
NSString *yes0 = @"yes";
NSString *yes1 = @"YES";
NSString *yes2 = [NSString stringWithFormat:@"%@", yes1];
 
NSArray *yesArray = [NSArray arrayWithObjects:yes0, yes1, yes2, nil];
 
NSUInteger index;
 
index = [yesArray indexOfObject:yes2];
// index is 1
 
index = [yesArray indexOfObjectIdenticalTo:yes2];
// index is 2
排序数组:可以用descriptor,block和selector
sortDescriptor可以方便的进行排序,并且可以和cocoa框架相结合,例如,对coreData的fetch request数据进行排序,可以使用sortedArrayUsingDescriptors:和sortUsingDescriptors:,代码如下:
//First create the array of dictionaries
NSString *last = @"lastName";
NSString *first = @"firstName";
 
NSMutableArray *array = [NSMutableArray array];
NSArray *sortedArray;
 
NSDictionary *dict;
dict = [NSDictionary dictionaryWithObjectsAndKeys:
                     @"Jo", first, @"Smith", last, nil];
[array addObject:dict];
 
dict = [NSDictionary dictionaryWithObjectsAndKeys:
                     @"Joe", first, @"Smith", last, nil];
[array addObject:dict];
 
dict = [NSDictionary dictionaryWithObjectsAndKeys:
                     @"Joe", first, @"Smythe", last, nil];
[array addObject:dict];
 
dict = [NSDictionary dictionaryWithObjectsAndKeys:
                     @"Joanne", first, @"Smith", last, nil];
[array addObject:dict];
 
dict = [NSDictionary dictionaryWithObjectsAndKeys:
                     @"Robert", first, @"Jones", last, nil];
[array addObject:dict];
 
//Next we sort the contents of the array by last name then first name
 
// The results are likely to be shown to a user
// Note the use of the localizedCaseInsensitiveCompare: selector
NSSortDescriptor *lastDescriptor =
    [[NSSortDescriptor alloc] initWithKey:last
                               ascending:YES
                               selector:@selector(localizedCaseInsensitiveCompare:)];
NSSortDescriptor *firstDescriptor =
    [[NSSortDescriptor alloc] initWithKey:first
                               ascending:YES
                               selector:@selector(localizedCaseInsensitiveCompare:)];
 
NSArray *descriptors = [NSArray arrayWithObjects:lastDescriptor, firstDescriptor, nil];
sortedArray = [array sortedArrayUsingDescriptors:descriptors];
相比之下,function不是很灵活
NSInteger lastNameFirstNameSort(id person1, id person2, void *reverse)
{
    NSString *name1 = [person1 valueForKey:last];
    NSString *name2 = [person2 valueForKey:last];
 
    NSComparisonResult comparison = [name1 localizedCaseInsensitiveCompare:name2];
    if (comparison == NSOrderedSame) {
 
        name1 = [person1 valueForKey:first];
        name2 = [person2 valueForKey:first];
        comparison = [name1 localizedCaseInsensitiveCompare:name2];
    }
 
    if (*(BOOL *)reverse == YES) {
        return 0 - comparison;
    }
    return comparison;
}
 
BOOL reverseSort = YES;
sortedArray = [array sortedArrayUsingFunction:lastNameFirstNameSort
        context:&reverseSort];
使用Block,sortedArrayUsingComparator:或sortUsingComparator:
SArray *sortedArray = [array sortedArrayUsingComparator: ^(id obj1, id obj2) {
 
     if ([obj1 integerValue] > [obj2 integerValue]) {
          return (NSComparisonResult)NSOrderedDescending;
     }
 
     if ([obj1 integerValue] < [obj2 integerValue]) {
          return (NSComparisonResult)NSOrderedAscending;
     }
     return (NSComparisonResult)NSOrderedSame;
}];
使用SelectorsortedArrayUsingSelector:,sortedArrayUsingFunction:context:,或sortedArrayUsingFunction:context:hint:.其中hint是非常高效的,当我们对N个数组进行排序(进行p<<N个添加和删除的时候)
NSInteger alphabeticSort(id string1, id string2, void *reverse)
{
    if (*(BOOL *)reverse == YES) {
        return [string2 localizedCaseInsensitiveCompare:string1];
    }
    return [string1 localizedCaseInsensitiveCompare:string2];
}
 
NSMutableArray *anArray =
    [NSMutableArray arrayWithObjects:@"aa", @"ab", @"ac", @"ad", @"ae", @"af", @"ag",
        @"ah", @"ai", @"aj", @"ak", @"al", @"am", @"an", @"ao", @"ap", @"aq", @"ar", @"as", @"at",
        @"au", @"av", @"aw", @"ax", @"ay", @"az", @"ba", @"bb", @"bc", @"bd", @"bf", @"bg", @"bh",
        @"bi", @"bj", @"bk", @"bl", @"bm", @"bn", @"bo", @"bp", @"bq", @"br", @"bs", @"bt", @"bu",
        @"bv", @"bw", @"bx", @"by", @"bz", @"ca", @"cb", @"cc", @"cd", @"ce", @"cf", @"cg", @"ch",
        @"ci", @"cj", @"ck", @"cl", @"cm", @"cn", @"co", @"cp", @"cq", @"cr", @"cs", @"ct", @"cu",
        @"cv", @"cw", @"cx", @"cy", @"cz", nil];
// note: anArray is sorted
NSData *sortedArrayHint = [anArray sortedArrayHint];
 
[anArray insertObject:@"be" atIndex:5];
 
NSArray *sortedArray;
 
// sort using a selector
sortedArray =
        [anArray sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
 
// sort using a function
BOOL reverseSort = NO;
sortedArray =
        [anArray sortedArrayUsingFunction:alphabeticSort context:&reverseSort];
 
// sort with a hint
sortedArray =
        [anArray sortedArrayUsingFunction:alphabeticSort
                                  context:&reverseSort
                                     hint:sortedArrayHint];
注:字符串的比较使用localize,因为不同语言导致排序可能不一样
数组过滤
使用断言进行数组过滤,还可以使用IndexSet进行过滤,断言编程指导:https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Predicates/AdditionalChapters/Introduction.html#//apple_ref/doc/uid/TP40001789
NSMutableArray *array =
    [NSMutableArray arrayWithObjects:@"Bill", @"Ben", @"Chris", @"Melissa", nil];
 
NSPredicate *bPredicate =
    [NSPredicate predicateWithFormat:@"SELF beginswith[c] 'b'"];
NSArray *beginWithB =
    [array filteredArrayUsingPredicate:bPredicate];
// beginWithB contains { @"Bill", @"Ben" }.
 
NSPredicate *sPredicate =
    [NSPredicate predicateWithFormat:@"SELF contains[c] 's'"];
[array filterUsingPredicate:sPredicate];
// array now contains { @"Chris", @"Melissa" }
指针数组
对数据进行弱引用,可以存储nil对象,count计算时包含弱引用对象

可以指定任意类型,需要配置为NSPointerFunctionsOpaqueMemory and NSPointerFunctionsOpaquePersonality ,但是如果访问了一个函数栈空间的局部变量会导致错误,未定义的行为
NSPointerFunctionsOptions options=(NSPointerFunctionsOpaqueMemory |
     NSPointerFunctionsOpaquePersonality);
 
NSPointerArray *ptrArray=[NSPointerArray pointerArrayWithOptions: options];
 
[ptrArray addPointer: someIntPtr];
访问
NSLog(@" Index 0 contains: %i", *(int *) [ptrArray pointerAtIndex: 0] );
字典和集合在操作上和数组类似,不再进行详细描述
原文地址: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Collections/Collections.html










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值