NSArray简单细说(六)—— 向数组中元素发送消息

版本记录

版本号 时间
V1.0 2017.08.25

前言

NSArray是集合类型中的一种,是OC中很重要的概念,这个是我们一定会用到的对象,下面我就继续由整体到细节,由简单到复杂的和大家说一下它的用法。感兴趣的可以看我写的上篇几篇。
1. NSArray简单细说(一)—— 整体了解
2. NSArray简单细说(二)—— 数组的创建
3. NSArray简单细说(三)—— 数组初始化
4. NSArray简单细说(四)—— 数组的查询与检索
5. NSArray简单细说(五)—— 数组中对象的查找

一、- (void)makeObjectsPerformSelector:(SEL)aSelector;

该方法的作用就是:向数组中的每个对象发送由给定选择器标识的消息,从第一个对象开始,并通过数组继续到最后一个对象。

看一下参数,标识要发送到数组中的对象的消息的选择器。 该方法不能接受任何参数,也不能具有修改接收数组的影响。

如果aSelectorNULL,则此方法会引发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方法,作为参数发送的对象。

还有下面几点需要注意:

  • 如果aSelectorNULL,则此方法会引发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:要枚举的对象的索引。
  • optsblock的参数就不多说了,以前已经写的很清楚了。

这里还要注意:

  • 默认情况下,枚举从第一个对象开始,并且通过数组连续地继续到由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

结论:这个也值得一看的。

后记

未完,待续~~~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容