代码之家  ›  专栏  ›  技术社区  ›  Allyn

生成对象表单选择器:

  •  17
  • Allyn  · 技术社区  · 15 年前

    我想让数组中的所有对象执行选择器。我发现了 makeObjectsPerformSelector: 方法,但我有一个问题。如果我在一个数组上使用它,它会改变现有的数组还是返回一个新的数组?如果它修改了现有的对象,那么使用选择器返回新数组的最简单方法是什么?

    5 回复  |  直到 6 年前
        1
  •  29
  •   Sam    10 年前

    MakeObjectsPerFormSelector:将针对数组中的每个对象运行该选择器。如果这些对象被选择器修改,它们将被修改。它不返回任何内容。现在,有一个catch,默认情况下,cocoa中的大多数副本都是浅副本,这意味着您得到了一个新的数组,但它指向的底层对象是相同的对象。您将需要使用initwitharray:copy items来让它也复制根级别的项。如果希望包含更改对象和旧数组的新数组执行以下操作:

    NSArray *newArray = [[NSArray alloc] initWithArray:oldArray copyItems:YES];
    [newArray makeObjectsPerformSelector:@selector(doSomethingToObject)];
    
        2
  •  15
  •   Peter Hosey    15 年前

    如果我在一个数组上使用它,它会改变现有的数组还是返回一个新的数组?

    不。

    首先,阅读签名:

    - (void)makeObjectsPerformSelector:(SEL)aSelector
    

    void 如果后面没有星星,表示__不返回任何__。

    第二,注意这是一个nsarray方法,它是一个不可变的类。因此, makeObjectsPerformSelector: 不会改变接收阵列,因为这是不可能的。

    有NSmutableArray,由于它是NSarray的一个子类,所以它继承了 生成对象表单选择器: . 但是,如果nsmutableArray改变了该方法的行为,那么它的文档中会有它自己的方法列表(参见 init 在各种类别的文档中)。没有这样的列表,所以您可以安全地(正确地)推断 -[NSMutableArray makeObjectsPerformSelector:] 工作原理与 -[NSArray makeObjectsPerformSelector:] .

    对象可以根据您的消息修改自己_,但数组本身将在 生成对象表单选择器: 像以前一样。

        3
  •  7
  •   Mike Abdullah    15 年前

    其他答案,如果你 要使用调用方法的结果创建新数组,可以执行以下操作:

    NSArray *derivedArray = [originalArray valueForKey:@"foo"];
    

    本遗嘱 只有 如果对象可以处理'-valueforkey:@“foo”'消息,并且显然,它只适用于不带参数并返回非零值的方法。

        4
  •  2
  •   Terry Wilcox    15 年前

    我希望我能正确地解释…

    如果执行[MyArray MakeObjectsPerFormSelector:SomeSelector]操作,那么实际上只需迭代MyArray并向每个对象发送选择器消息。数组未更改,因为不允许MakeObjectsPerFormSelector更改其内容。

    因此,最后,您得到了具有相同对象的相同数组。

        5
  •  0
  •   Esmaeil    6 年前

    在下面的示例中,您可以看到一个 superView 创建并添加10个子视图,然后发送给每个子视图 removeFromSuperView (存在于 view 类),结果是零个子视图 超视点 .

    如果您熟悉JavaScript并尝试查找类似 map 在JavaScript中,这不是这样的。 地图 在数组的每个元素上运行一个函数,并用结果替换它,但这里 makeObjectsPerformSelector 运行存在于数组的每个对象中的方法。

    UIView* superView = [[UIView alloc] initWithFrame:CGRectZero];
    
    for(int i = 0; i < 10; i++){
        UIView* view = [[UIView alloc] initWithFrame:CGRectZero];
        [superView addSubview:view];
    }
    
    NSLog(@"count = %lu", (unsigned long)[superView.subviews count]); // 10
    [superView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; // removeFromSuperview is exist in `view`, you can call [view removeFromSuperview];
    NSLog(@"count = %lu", (unsigned long)[superView.subviews count]); // 0