NSArray&NSMutableArray 高端用法


Cocoa的NSArray是基于C底层CFArray/CFArrayRef实现的,NSArray可以看做是一个CFArrayRef的Wrapper类。__NSArrayIImmutable)是NSArray的真正类型,__NSArrayMMutable是NSMutableArray的真正类型。

NSArray保存的对象可以是不同类型的对象,但只能保存OC对象(继承自NSObject),int,char,double等基本C数据类型不能直接保存,需要通过装箱(boxing)成NSNumber、NSString或NSValue对象才能加入数组。

在苹果WWDC2012大会上介绍了大量Objective-C的新特性,其中有一点就是Object Literals,它允许你方便地基于字面量定义数字、数组和字典对象。

字面语法是的编译器指令,它提供简化符号来创建对象,类似于java5提供的auto boxing功能。这虽然是一个语法糖,但对提高写代码效率帮助很大。以下代码片段基于字面量语法快捷初始化数组(NSArray):

[objc]  view plain copy print ?
  1. NSString* yy = @"2015";  
  2. NSNumber* mm = @(07);  
  3. NSValue* dd = @(26);  
  4. NSArray* array = @[yy, mm, dd]; // 都是NSObject对象  
  5. NSLog(@"array = %@", array);  

 1.创建初始化(Initialization&Creation

Each object in array simply receives a retain message when it is added to the returned array using initWith*/arrayWith* method.

After an immutable array has been initialized in the following way, it cannot be modified.

1.1 Initializing an Array(NS_DESIGNATED_INITIALIZER)

[objc]  view plain copy print ?
  1. // Initializes a newly allocated array. Not recommended for immutable array as  it's empty!  
  2. - (instancetype)init NS_DESIGNATED_INITIALIZER;  
  3. - (instancetype)initWithObjects:(const id[])objects count:(NSUInteger)cnt NS_DESIGNATED_INITIALIZER;  
  4. - (instancetype)initWithObjects:(id)firstObj, ... NS_REQUIRES_NIL_TERMINATION;  
  5. - (instancetype)initWithArray:(NSArray *)array;  
  6. // If YES, each object in array receives a copyWithZone: message to create a copy of the object instead of the retain message.  
  7. - (instancetype)initWithArray:(NSArray *)array copyItems:(BOOL)flag;  
以下是比较常用的初始化方法:

- (instancetype)initWithObjects:(id)firstObj, ... NS_REQUIRES_NIL_TERMINATION;

1.2 Creating an Array(autorelease)

[objc]  view plain copy print ?
  1. // Creates and returns an empty array. This method is used by mutable subclasses of NSArray.  
  2. + (instancetype)array;  
  3. + (instancetype)arrayWithObject:(id)anObject;  
  4. + (instancetype)arrayWithObjects:(const id[])objects count:(NSUInteger)cnt; // initWithObjects:count:  
  5. + (instancetype)arrayWithObjects:(id)firstObj, ...NS_REQUIRES_NIL_TERMINATION// initWithObjects:count:  
  6. + (instancetype)arrayWithArray:(NSArray*)array; // initWithArray:  

以下是比较常用的类方法便利构造方法:

+ (instancetype)arrayWithObjects:(id)firstObj, ...NS_REQUIRES_NIL_TERMINATION; // initWithObjects:count:

+ (instancetype)arrayWithArray:(NSArray*)array; // initWithArray:


2.访问数组(Querying

2.1 数组描述

[objc]  view plain copy print ?
  1. @property (readonly,copy)NSString *description;  

例如以下代码可以在调试时打印数组:

[objc]  view plain copy print ?
  1. NSArray* array = [NSArray arrayWithObjects:@"e0",@"e1",@"e2",@"e3",@"e4",@"e5",@"e6",nil];  
  2. NSLog(@"array = %@", array);  
  3. NSLog(@"array = %@", array.description);  

2.2 数组大小

[objc]  view plain copy print ?
  1. //返回数组所包含的元素(NSObject对象)个数  
  2. @property (readonly)NSUInteger count;  

可以基于array.count对数组进行判空:如果array.count=0,则表示数组为nil或不包含任何元素。

2.3 数组元素 

[objc]  view plain copy print ?
  1. //返回数组第一个元素  
  2. @property (nonatomic,readonly)id firstObject NS_AVAILABLE(10_6,4_0);  
  3. @property (nonatomic,readonly)id lastObject;  
  4.    
  5. //判断数组是否包含某个元素(按值查询)  
  6. - (BOOL)containsObject:(id)anObject;  
  7.    
  8. //等效于objectAtIndex,支持中括号下标格式(array[index])访问指定索引元素。  
  9. - (id)objectAtIndexedSubscript:(NSUInteger)idx NS_AVAILABLE(10_8,6_0);  
  10.    
  11. //返回数组指定索引位置的元素,索引范围[0, count-1]  
  12. - (id)objectAtIndex:(NSUInteger)index;  
  13.    
  14. //返回数组指定索引集的元素组成的子数组  
  15. - (NSArray *)objectsAtIndexes:(NSIndexSet *)indexes;  
  • objectAtIndex:方法用于快速返回指定索引位置的元素;firstObjectlastObject属性用于快捷访问数组的首、尾元素。
  • containsObject:方法用于按值搜索查询数组是否包含某个元素。

以下代码获取第2、4、6个元素子数组:

[objc]  view plain copy print ?
  1. NSMutableIndexSet* indexSet = [NSMutableIndexSet indexSet];  
  2. [indexSet addIndex:1];  
  3. [indexSet addIndex:3];  
  4. [indexSet addIndex:5];  
  5. NSArray* subArray = [array objectsAtIndexes:indexSet];  
  6. NSLog(@"subArray= %@", subArray);  
等效于:

[objc]  view plain copy print ?
  1. NSArray* subArray = [NSArray arrayWithObjects:[ array objectAtIndex:1], [array objectAtIndex:3], [array objectAtIndex:5], nil nil];  

2.4遍历数组

(1)索引遍历

[objc]  view plain copy print ?
  1. // 倒序:for (NSInteger index=array.count-1; index>=0; index--)  
  2. for (NSUInteger index=0; index<array.count; index++)  
  3. {  
  4.     NSLog(@"array[%zd] = %@", index, [array objectAtIndex:index]); // array[index]  
  5. }  

(2)枚举遍历

[objc]  view plain copy print ?
  1. // 倒序:reverseObjectEnumerator  
  2. NSEnumerator* enumerator = [array objectEnumerator];  
  3. id e = nil;  
  4. while (e = [enumerator nextObject])  
  5. {  
  6.     NSLog(@"e = %@", e);  
  7. }  
  8.   
  9. /* 
  10. for (id e in enumerator) { 
  11.     NSLog(@"e = %@",e); 
  12. } 
  13. */  

使用代码块传递遍历操作:

- (void)enumerateObjectsUsingBlock:(void (^)(id obj,NSUInteger idx,BOOL *stop))block NS_AVAILABLE(10_6,4_0);

[objc]  view plain copy print ?
  1. // 示例1:枚举遍历  
  2. [array enumerateObjectsUsingBlock:^ (id obj, NSUInteger idx, BOOLBOOL *stop){  
  3.     NSLog(@"obj = %@", obj);  
  4. }];  
  5.   
  6. // 示例2:枚举遍历,遇到符合条件的元素即退出遍历。  
  7. [array enumerateObjectsUsingBlock:^ (id obj, NSUInteger idx, BOOLBOOL *stop){  
  8.     if ([obj isEqualToString:@"e3"]) {  
  9.         *stop = YES// 中止遍历, break  
  10.     } else {  
  11.         *stop = NO// 继续遍历,continue  
  12.     }  
  13. }];  

以上版本默认是顺序同步遍历,另外一个版本可以指定NSEnumerationOptions参数:

[objc]  view plain copy print ?
  1. typedefNS_OPTIONS(NSUInteger, NSEnumerationOptions) {  
  2.     NSEnumerationConcurrent = (1UL <<0),// block并发  
  3.     NSEnumerationReverse = (1UL <<1),//倒序  
  4. };  

(3)快速遍历

[objc]  view plain copy print ?
  1. for (id e in array) {  
  2.     NSLog(@"e = %@", e);  
  3. }  


3.查询数组(Finding

3.1 indexOfObject(IdenticalTo)

[objc]  view plain copy print ?
  1. // 在数组(或指定范围)中,测试指定的对象是否在数组中(按值查询)  
  2. - (NSUInteger)indexOfObject:(id)anObject; // 同containsObject  
  3. - (NSUInteger)indexOfObject:(id)anObject inRange:(NSRange)range;  
  4. // 测试指定的对象是否在数组中(按指针查询)  
  5. - (NSUInteger)indexOfObjectIdenticalTo:(id)anObject;  
  6. - (NSUInteger)indexOfObjectIdenticalTo:(id)anObject inRange:(NSRange)range;  

3.2 indexOfObject(s)PassingTest

使用代码块传递遍历操作过滤条件:

[objc]  view plain copy print ?
  1. //查找数组中第一个符合条件的对象(代码块过滤),返回对应索引  
  2. - (NSUInteger)indexOfObjectPassingTest:(BOOL (^)(id obj,NSUInteger idx, BOOLBOOL *stop))predicate NS_AVAILABLE(10_6,4_0);  

以下代码用于获取值等于@"e3"的元素索引:

[objc]  view plain copy print ?
  1. NSUInteger index = [array indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOLBOOL *stop) {  
  2.     if ([obj isEqualToString:@"e3"]) {  
  3.         return YES;  
  4.         *stop = YES// 中止遍历,break  
  5.     } else {  
  6.         *stop = NO// 继续遍历,continue  
  7.     }  
  8. }];  

查找数组中所有符合条件的对象(代码块过滤),返回对应索引集合:

[objc]  view plain copy print ?
  1. - (NSIndexSet *)indexesOfObjectsPassingTest:(BOOL (^)(id obj,NSUInteger idx, BOOLBOOL *stop)) predicate NS_AVAILABLE(10_6,4_0);  


以上indexesOfObjectPassingTest/ indexesOfObjectsPassingTest版本默认是顺序同步遍历,它们都有另外可以指定NSEnumerationOptions参数的扩展版本。

indexOfObjectAtIndexes:options:passingTest:和indexOfObjectsAtIndexes:options:passingTest:则是指定索引集合内查找并返回索引(集合)。

3.3 firstObjectCommonWithArray

[objc]  view plain copy print ?
  1. //查找与给定数组中第一个相同的对象(按值)  
  2. - (id)firstObjectCommonWithArray:(NSArray *)otherArray;  

示例:

[objc]  view plain copy print ?
  1. id fo = [array firstObjectCommonWithArray:subArray];  
  2. NSLog(@"fo= %@", fo); // e1  


4.衍生数组(Deriving

[objc]  view plain copy print ?
  1. //返回指定范围(起始索引、长度)的子数组  
  2. -  (NSArray *)subarrayWithRange:(NSRange)range;  

以下代码获取数组前一半子数组:

[objc]  view plain copy print ?
  1. //return the first half of the whole array  
  2. NSArray* subArray = [array subarrayWithRange:NSMakeRange(0,array.count/2)];  
  3. NSLog(@"subArray= %@", subArray);  


[objc]  view plain copy print ?
  1. //在当前数组追加元素或数组,并返回新数组对象  
  2. - (NSArray *)arrayByAddingObject:(id)anObject;  
  3. - (NSArray *)arrayByAddingObjectsFromArray:(NSArray *)otherArray;  


5.可变数组(NSMutableArray)

5.1 Initializing an Array(NS_DESIGNATED_INITIALIZER)

除了继承NSArray基本的init,还增加了以下指定初始化函数

[objc]  view plain copy print ?
  1. - (instancetype)initWithCapacity:(NSUInteger)numItemsNS_DESIGNATED_INITIALIZER;  

5.2 addObject

[objc]  view plain copy print ?
  1. //尾部追加一个元素  
  2. - (void)addObject:(id)anObject;  
  3. //尾部追加一个数组  
  4. - (void)addObjectsFromArray:(NSArray *)otherArray;  

5.3 insertObject

[objc]  view plain copy print ?
  1. //在指定索引处插入一个元素,原来的元素后移  
  2. // index取值范围=[0, count],index=count时相当于addObject  
  3. - (void)insertObject:(id)anObject atIndex:(NSUInteger)index;  
  4. //在指定索引集合处插入一个数组元素,相当于批次insertObject: atIndex:  
  5. - (void)insertObjects:(NSArray *)objects atIndexes:(NSIndexSet*)indexes;  

5.4 exchangeObject/replaceObject

[objc]  view plain copy print ?
  1. //交换对应索引位置的元素(索引必须有效)  
  2. - (void)exchangeObjectAtIndex:(NSUInteger)idx1 withObjectAtIndex:(NSUInteger)idx2;  
  3.    
  4. //替换对应索引位置的元素(索引必须有效)  
  5. - (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject;  
  6. //替换对应索引集合位置的元素,相当于批次replaceObjectAtIndex: withObject:  
  7. - (void)replaceObjectsAtIndexes:(NSIndexSet *)indexes withObjects:(NSArray*)objects;  
  8.    
  9. //等效于replaceObjectAtIndex,支持中括号下标格式(array[index])赋值替换。  
  10. // index取值范围=[0, count],index=count时相当于addObject  
  11. - (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idxNS_AVAILABLE(10_8,6_0);  
  12. //等效于先removeAllObjects后addObjectsFromArray  
  13. - (void)setArray:(NSArray *)otherArray;  

5.5 removeObject 

[objc]  view plain copy print ?
  1. - (void)removeLastObject;  
  2. //删除对应索引位置/范围的元素(索引/范围必须有效)  
  3. - (void)removeObjectAtIndex:(NSUInteger)index;  
  4. - (void)removeObjectsAtIndexes:(NSIndexSet *)indexes;  
  5. - (void)removeObjectsInRange:(NSRange)range;  
  6. //有则删除  
  7. - (void)removeObject:(id)anObject;  
  8. - (void)removeObject:(id)anObject inRange:(NSRange)range;  
  9. - (void)removeObjectsInArray:(NSArray *)otherArray;  
  10. - (void)removeAllObjects;  


6.数组排序(Sorting

略。


参考:

iOS之NSArray方法详解

Objective-C研究院之数组对象(七)

Objective-C语法之NSArray和NSMutableArray

Objective-C数组对象(NSArray和NSMutableArrray)

NSArray排序方法
iOS探索:对NSArray中自定义的对象进行排序


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值