版本记录
版本号 | 时间 |
---|---|
V1.0 | 2017.08.25 |
前言
NSArray
是集合类型中的一种,是OC中很重要的概念,这个是我们一定会用到的对象,下面我就继续由整体到细节,由简单到复杂的和大家说一下它的用法。感兴趣的可以看我写的上篇几篇。
1. NSArray简单细说(一)—— 整体了解
2. NSArray简单细说(二)—— 数组的创建
3. NSArray简单细说(三)—— 数组初始化
4. NSArray简单细说(四)—— 数组的查询与检索
5. NSArray简单细说(五)—— 数组中对象的查找
一、- (void)makeObjectsPerformSelector:(SEL)aSelector;
该方法的作用就是:向数组中的每个对象发送由给定选择器标识的消息,从第一个对象开始,并通过数组继续到最后一个对象。
看一下参数,标识要发送到数组中的对象的消息的选择器。 该方法不能接受任何参数,也不能具有修改接收数组的影响。
如果aSelector
为NULL
,则此方法会引发NSInvalidArgumentException
异常。
下面那我们就看一下一个代码。
- (void)demoMakeObjectsPerformSelector
{
NSArray *arr = @[@1, @2, @3];
[arr makeObjectsPerformSelector:@selector(floatValue)];
}
上面这个就是示例代码,作用就是让数组中的每一个元素都执行floatValue
这个方法,这里是运行不通的,因为NSNumber对象并没有我自定义的floatValue
方法。这个方法已经废弃不用的了。Use enumerateObjectsUsingBlock: or a for loop instead
。
可以向下面这么使用:将self.view
的上的子视图逐一从父视图上移除
[self.view.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
结论:已经不常用了,看明白即可。
二、- (void)makeObjectsPerformSelector:(SEL)aSelector withObject:(id)argument;
该方法的作用就是:将aSelector消息发送到数组中的每个对象,从第一个对象开始,并通过数组继续到最后一个对象。
下面我们看一下参数:
-
aSelector
:标识要发送到数组中的对象的消息的选择器。 该方法必须使用类型为id的单个参数,并且不得具有修改接收数组的作用。 -
argument
:每次调用aSelector方法,作为参数发送的对象。
还有下面几点需要注意:
- 如果
aSelector
为NULL
,则此方法会引发NSInvalidArgumentException
异常。
下面还是看代码
- (void)demoMakeObjectsPerformSelectorWithObject
{
NSArray *arr = @[@1, @2, @3];
[arr makeObjectsPerformSelector:@selector(compare:) withObject:@2];
}
这个方法的意思就是用数组中的每一个元素调用compare:
方法,并且传入一个参数,我这里传入的就是@2。
这个方法一样被废弃了。
结论:已经不常用了,看明白即可。
三、- (void)enumerateObjectsUsingBlock:(void (^)(ObjectType obj, NSUInteger idx, BOOL *stop))block;
该方法的作用就是:使用数组中的每个对象执行给定的块,从第一个对象开始,并通过数组继续到最后一个对象。
下面我们就说一下参数
- block
- obj :数组中的元素。
- idx:数值中元素的索引。
- stop:对布尔值的引用。 该块可以将值设置为YES以停止对数组的进一步枚举。 如果一个程序段停止进一步的枚举,该程序段将继续运行直到完成。 停止参数是一个out-only参数。 您应该只在块中将此布尔值设置为YES。
还有几点需要注意:
- 如果block参数为nil,此方法将引发异常。 在块中分配的值将在块执行后被释放。 使用retain来明确维护这些值。该方法同步执行。
下面看一下代码
- (void)demoEnumerateObjectsUsingBlock
{
NSArray *arr = @[@1, @2, @3];
[arr enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSLog(@"obj = %@", obj);
if ([obj integerValue] == 2) {
*stop = YES;
}
}];
}
下面看输出结果
2017-08-25 17:05:10.878 JJOC[2391:37858] obj = 1
2017-08-25 17:05:10.878 JJOC[2391:37858] obj = 2
结论:该方法非常非常重要,数组遍历的不二选择。
四、- (void)enumerateObjectsWithOptions:(NSEnumerationOptions)opts usingBlock:(void (^)(ObjectType obj, NSUInteger idx, BOOL *stop))block;
该方法的作用就是:用数组中的每一个元素执行block块。
下面我们看一下参数:
-
opts
:一个位掩码,指定枚举的选项(是否应同时执行,是否应以相反的顺序执行)。这个值是一个枚举,如下所示:
typedef NS_OPTIONS(NSUInteger, NSEnumerationOptions) {
NSEnumerationConcurrent = (1UL << 0),
NSEnumerationReverse = (1UL << 1),
};
-
stop
:对布尔值的引用。 该块可以将值设置为YES以停止对数组的进一步枚举。 如果一个程序段停止进一步的枚举,该程序段将继续运行直到完成。 当指定NSEnumerationConcurrent
枚举选项时,所有当前运行的块完成后,枚举停止。 停止参数是一个out-only
参数。 您应该只在块中将此布尔值设置为YES。
还有几点需要注意:
- 默认情况下,枚举从第一个对象开始,并通过数组连续地继续到最后一个对象。 您可以指定
NSEnumerationConcurrent
和/或NSEnumerationReverse
作为枚举选项来修改此行为。该方法同步执行。 - 如果block参数为nil,此方法将引发异常。
下面我们就看一下代码
- (void)demoEnumerateObjectsWithOptions
{
NSArray *arr = @[@1, @2, @3];
[arr enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSLog(@"obj = %@", obj);
if ([obj integerValue] == 2) {
*stop = YES;
}
}];
}
下面看输出
2017-08-25 17:12:59.043 JJOC[2625:45174] obj = 3
2017-08-25 17:12:59.043 JJOC[2625:45174] obj = 2
结论:该方法仍然非常重要,需要理解熟记。
五、- (void)enumerateObjectsAtIndexes:(NSIndexSet *)s options:(NSEnumerationOptions)opts usingBlock:(void (^)(ObjectType obj, NSUInteger idx, BOOL *stop))block;
该方法的作用就是:使用指定索引的数组中的对象执行给定的块。
下面我们看一下参数:
-
s
:要枚举的对象的索引。 -
opts
和block
的参数就不多说了,以前已经写的很清楚了。
这里还要注意:
- 默认情况下,枚举从第一个对象开始,并且通过数组连续地继续到由indexSet指定的最后一个元素。 您可以指定
NSEnumerationConcurrent
和/或NSEnumerationReverse
作为枚举选项来修改此行为,该方法同步执行。 - 如果block参数或
indexSet
为nil,此方法将引发异常。
下面我们看代码
- (void)demoEnumerateObjectsAtIndexes
{
NSArray *arr = @[@1, @2, @3];
NSIndexSet *set = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 2)];
[arr enumerateObjectsAtIndexes:set options:NSEnumerationConcurrent usingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSLog(@"obj = %@", obj);
if ([obj integerValue] == 2) {
*stop = YES;
}
}];
}
下面看输出结果
2017-08-25 17:36:17.119 JJOC[3131:61583] obj = 1
2017-08-25 17:36:17.119 JJOC[3131:61583] obj = 2
结论:这个也值得一看的。
后记
未完,待续~~~