Objective-C - 直接从对象数组中调用方法

时间:2011-09-22 04:03:41

标签: objective-c

我是Objective C的新手,我正试图直接调用对象的数组(NSArray)上的方法:

[[myPeople objectAtIndex: 0] setName: @"Shane"];

但这似乎不起作用,并返回一条警告,说“已找到多个名为'setName'的方法”

我可以这样成功地执行操作:

Person* person = [myPeople objectAtIndex: 0];
[person setName: @"Shane"];

我的语法在第一种情况下是不正确的,还是应该使用第二段代码?或者有更好的方法我不知道吗?

谢谢,非常感谢任何帮助

3 个答案:

答案 0 :(得分:8)

您可以像这样对数组中的所有对象执行此操作:

[myPeople makeObjectsPerformSelector:@selector(setName:) withObject:@"Shane"];

答案 1 :(得分:3)

第一种语法是正确的,尽管有警告,但仍能正常工作。编译器警告您,因为它无法验证您正在调用setName:的对象类型。

objectAtIndex:类的方法NSArray返回类型id,它是指向未知类型的Objective-C对象的通用指针。因此,当您在返回的setName:上调用id时,编译器不知道该对象的实际类是什么。在您的代码中,有多个类定义setName:方法(可能作为名为name的属性的合成setter),因此它会发出警告。

第二个代码片段在没有警告的情况下编译,因为id类型可以隐式地转换为任何其他Objective-C指针类型。当您说Person* person = [myPeople objectAtIndex: 0];时,您正在接受id返回的objectAtIndex:并将其(隐式)投射到Person*。然后,当您在setName:上调用Person时,编译器会知道您拥有的类型,因此它可以验证类Person实际上是否实现了setName:方法。

答案 2 :(得分:3)

如果要绕过编译器警告。还有另外两种方法,然后是你演示的方法。

你可以调用performSelector:withObject。

[[myPeople objectAtIndex: 0] performSelector:@selector(setName:) withObject: @"Shane"];

通常使用此方法,您需要确保它响应选择器。

if ([[myPeople objectAtIndex: 0] respondsToSelector:@selector(setName:)])

另一种选择是投射结果

[(Person*)[myPeople objectAtIndex: 0] setName: @"Shane"];

这些应该消除编译器警告。