我想让数组中的所有对象都执行选择器。我发现了适当命名的makeObjectsPerformSelector:
方法,但我有一个问题。如果我在数组上使用它,它会更改现有数组还是返回一个新数组?如果它修改了现有对象,那么在应用选择器的情况下返回新数组的最简单方法是什么?
答案 0 :(得分:29)
makeObjectsPerformSelector:将针对数组中的每个对象运行该选择器。如果选择器修改了这些对象,则会修改它们。它没有返回任何东西。现在,有一个catch,默认情况下,Cocoa中的大多数副本都是浅拷贝,这意味着你得到一个新的数组,但它指向的底层对象是相同的对象。您将需要使用initWithArray:copyItems来复制根级项目。如果你想要一个包含已更改对象的新数组以及旧数组,请执行以下操作:
NSArray *newArray = [[NSArray alloc] initWithArray:oldArray copyItems:YES];
[newArray makeObjectsPerformSelector:@selector(doSomethingToObject)];
答案 1 :(得分:15)
如果我在数组上使用它,它会更改现有数组还是返回一个新数组?
没有
首先,阅读签名:
- (void)makeObjectsPerformSelector:(SEL)aSelector
void
,之后没有明星,意味着“不会返回任何东西”。
其次,请注意,这是NSArray的一种方法,它是一个不可变类。因此,makeObjectsPerformSelector:
不会改变接收数组,因为这是不可能的。
有NSMutableArray,因为它是NSArray的子类,所以它继承了makeObjectsPerformSelector:
。但是,如果NSMutableArray更改了该方法的行为,则其文档将具有自己的方法列表(请参阅各种类文档中的init
的许多定义)。没有此类列表,因此您可以安全(并且正确)推断-[NSMutableArray makeObjectsPerformSelector:]
的工作方式与-[NSArray makeObjectsPerformSelector:]
完全相同。
对象可以自行修改以响应您的消息,但是数组本身将在makeObjectsPerformSelector:
之后包含与之前相同的对象。
答案 2 :(得分:7)
除了其他答案之外,如果你做想要创建一个调用方法的结果的新数组,你可以这样做:
NSArray *derivedArray = [originalArray valueForKey:@"foo"];
如果你的对象可以处理'-valueForKey:@“foo”'消息,那么只会工作,显然,它只适用于不带参数且返回非零值的方法。
答案 3 :(得分:2)
我希望我正确地解释这个......
如果你[myArray makeObjectsPerformSelector:someSelector],你实际上只是迭代myArray并将选择器消息发送到每个对象。数组未更改,因为不允许makeObjectsPerformSelector更改其内容。
所以最后,你得到了具有相同对象的相同数组。
答案 4 :(得分:0)
在下面的示例中,您可以看到已创建一个superView
并添加了10个子视图,然后向每个视图发送removeFromSuperView
(view
类中存在的一种方法)结果是superView
中的子视图为零。
如果您熟悉JavaScript并尝试在JavaScript中找到类似map
的东西,那就不是那样了。 map
在数组的每个元素上运行一个函数,并将其替换为结果,但此处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