objective-c makeObjectsPerformSelector:

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/563051/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 21:09:42  来源:igfitidea点击:

makeObjectsPerformSelector:

objective-carrayscocoansarray

提问by Allyn

I want to make all objects in an array perform a selector. I've discovered the appropriately named makeObjectsPerformSelector:method, but I have a question with it. If I use it on an array, will it change the existing array or return a new one? If it modifies the existing object, what be the easiest way to return a new array with the selector applied?

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

回答by Louis Gerbarg

makeObjectsPerformSelector: is going to run that selector against every object in the array. If those objects are modified by the selector they will be modified. It does not return anything. Now, there is a catch, which that by default most copies in Cocoa are shallow copies, which means you get a new array, but the underlying objects it points to are the same objects. You will need to use initWithArray:copyItems to make it copy the root level items as well. If you want a new array containing the altered objects as well as the old array do something like this:

makeObjectsPerformSelector: 将针对数组中的每个对象运行该选择器。如果这些对象被选择器修改,它们将被修改。它不返回任何东西。现在,有一个问题,默认情况下 Cocoa 中的大多数副本都是浅副本,这意味着您获得了一个新数组,但它指向的底层对象是相同的对象。您将需要使用 initWithArray:copyItems 使其也复制根级别的项目。如果您想要一个包含更改对象的新数组以及旧数组,请执行以下操作:

NSArray *newArray = [[NSArray alloc] initWithArray:oldArray copyItems:YES];
[newArray makeObjectsPerformSelector:@selector(doSomethingToObject)];

回答by Peter Hosey

If I use it on an array, will it change the existing array or return a new one?

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

No.

不。

First off, read the signature:

首先,阅读签名:

- (void)makeObjectsPerformSelector:(SEL)aSelector

void, with no stars after it, means “does not return anything”.

void,后面没有星号,意思是“不返回任何东西”。

Second, note that this is a method of NSArray, which is an immutable class. Therefore, makeObjectsPerformSelector:does not mutate the receiving array, because that's impossible.

其次,注意这是一个 NSArray 的方法,它是一个不可变的类。因此,makeObjectsPerformSelector:不会改变接收数组,因为那是不可能的。

There is NSMutableArray, and since that's a subclass of NSArray, it inherits makeObjectsPerformSelector:. However, if NSMutableArray changed that method's behavior, its documentation would have its own listing for the method (see the many definitions of initin various classes' documentation). There's no such listing, so you can safely (and correctly) infer that -[NSMutableArray makeObjectsPerformSelector:]works exactly the same way as -[NSArray makeObjectsPerformSelector:].

有 NSMutableArray,因为它是 NSArray 的子类,所以它继承了makeObjectsPerformSelector:. 但是,如果 NSMutableArray 更改了该方法的行为,则其文档将具有自己的方法列表(请参阅init各种类文档中的许多定义)。没有这样的列表,因此您可以安全地(并且正确地)推断它的-[NSMutableArray makeObjectsPerformSelector:]工作方式与-[NSArray makeObjectsPerformSelector:].

The objects can modify themselves?in response to your message, but the array itself will contain the same objects after makeObjectsPerformSelector:as before it.

对象可以修改自己?响应您的消息,但数组本身将包含与makeObjectsPerformSelector:之前相同的对象。

回答by Mike Abdullah

Further to other answers, if you dowant create a new array with the result of calling a method, you can do this:

除了其他答案之外,如果您确实想使用调用方法的结果创建一个新数组,您可以这样做:

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

This will onlywork if your objects can handle a '-valueForKey:@"foo"' message and obviously, is only suitable for methods which take no arguments and return a non-nil value.

在您的对象可以处理 '-valueForKey:@"foo"' 消息时才有效,并且显然只适用于不带参数并返回非 nil 值的方法。

回答by Terry Wilcox

I hope I'm interpreting this correctly...

我希望我能正确解释这一点......

If you do [myArray makeObjectsPerformSelector:someSelector], you're effectively just iterating through myArray and sending the selector message to each object. The array is unchanged because makeObjectsPerformSelector isn't allowed to change its contents.

如果您执行 [myArray makeObjectsPerformSelector:someSelector],您实际上只是遍历 myArray 并将选择器消息发送到每个对象。该数组未更改,因为不允许 makeObjectsPerformSelector 更改其内容。

So in the end, you've got the same array with the same objects.

所以最后,你得到了具有相同对象的相同数组。

回答by Esmaeil

In following example, You can see one superViewis created and 10 subview added to it, then to each of them send removeFromSuperView(a method which is exist in viewclass) and the result is zero subview in superView.

在以下示例中,您可以看到superView创建了一个并添加了 10 个子视图,然后向每个子视图发送removeFromSuperViewview类中存在的方法),结果在superView.

If you familiar with JavaScript and try to find something like mapin JavaScript, this is not like that. maprun a function over each element of array and replace it with result but here makeObjectsPerformSelectorrun a method that exist in each object of array.

如果你熟悉 JavaScript 并试图map在 JavaScript 中找到类似的东西,这不是那样的。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