for loops - 忽略对象类型?

时间:2011-08-17 21:44:40

标签: iphone objective-c for-loop nsarray

我有时喜欢将IB元素组织到NSArray中,主要是为了帮助我组织元素。通常,不同类别的对象使它们彼此成为相同的数组。虽然这个 是一种方便的组织方式,但我似乎无法理解为什么如果我有这样的数组:

NSArray *array = [NSArray arrayWithObjects:((UITextField *)textField), ((UISegmentedController *)segmentedController), nil];

当我像这样放置for循环时,为什么会出现“不响应选择器”消息:

for (UITextField *text in array) {
    [text setText:@""];
}

for循环似乎传递的是不属于UITextField类的对象。

如果指定数组中的所有对象都通过循环传递,则声明对象类的重点是什么?

编辑仅供参考,这就是我现在处理它的方式:

for (id *object in array) {
    if ([object isMemberOfClass:[UITextField class]]) {
        foo();
    } else if ([object isMemberOfClass:[UISegmentedController class]) {
        bar();
    }
 }

3 个答案:

答案 0 :(得分:10)

当你这样做时

for (UITextField *text in...

数组中的对象指针被强制转换为UITextField *类型 - 所以如果对象实际上不是UITextField,如果你试图调用UITextField方法,可能会发生各种奇怪的事情。

所以改为使用id类型(no * needed,btw):

for (id obj in array)

然后检查类型并调用相应的方法。或者,过滤数组以仅获取特定类型的对象,然后仅使用该类型:

for (UITextField* text in [array filteredArrayUsingPredicate:...])

编辑:这是如何构建类过滤谓词:

Is it possible to filter an NSArray by class?

答案 1 :(得分:5)

  

如果指定数组中的所有对象都通过循环传递,则声明对象类的重点是什么?

类名就是让编译器知道它应该找到什么。这允许它试图找出它应该让你调用的方法以及如何处理对象。这与将int传递给采用float的方法的想法相同。该方法不会忽略整数 - 它假设您传递的是正确的类型。你只是给这个结构一点点的信用额度:

for (UITextField *text in array)

它没有那个功能。你现在如何处理它是正确的方法。

答案 2 :(得分:0)

当您 运行 该代码时,您确定没有收到错误消息吗? “不响应选择器”消息是运行时错误,而不是编译时错误。编译器不知道数组中的对象是否实现-setText:,但当您实际将该消息发送到UISegmentedControl的实例时,您肯定会收到错误。

另一种可能性是你有一个名为UISegmentedController的类,它有一个-setText:方法。实现多部分条形图用户界面窗口小部件的类的名称是UISegmentedControl。因此,您要显示的代码不是真实的,经过测试的代码,或者您有一个我们不了解的类。