【问题标题】:NSMutableArray fast enumeration issueNSMutableArray 快速枚举问题
【发布时间】:2012-11-02 14:28:38
【问题描述】:

新手 obj-c 问题。

我有一个带有四个自定义单元格的自定义表格视图。每个单元格中都有一个用于客户信息的可编辑文本字段。我需要通过输入附件视图改进文本字段之间的切换。 http://uaimage.com/image/62f08045

我创建了一个容量为 4 的 NSMutableArray。我标记了文本字段并在文本字段委托方法中将它们添加到此数组中:

- (BOOL) textFieldShouldReturn:(UITextField *)textField {
    FDTextFieldCell *cell = (FDTextFieldCell *)[textField superview];
    NSIndexPath *indexPath = [[self tableView] indexPathForCell:cell];

    if ([indexPath section] == 0) {
        if ([indexPath row] == 0) {
            [[FDProfile sharedProfile] setName:[textField text]];
            [textField setTag:1];
            [textFieldsArray insertObject:textField atIndex:0];
        } else if ([indexPath row] == 1) {
            [[FDProfile sharedProfile] setSurname:[textField text]];
            [textField setTag:2];
            [textFieldsArray insertObject:textField atIndex:1];
        } else if ([indexPath row] == 2) {
            [[FDProfile sharedProfile] setNickname:[textField text]];
            [textField setTag:3];
            [textFieldsArray insertObject:textField atIndex:2];
        } else if ([indexPath row] == 3) {
            [[FDProfile sharedProfile] setEmail:[textField text]];
            [textField setTag:4];
            [textFieldsArray insertObject:textField atIndex:3];
            [textField resignFirstResponder];
        }
    }

    [[self tableView] reloadData];
    return YES;
}

现在我尝试改进“下一步”按钮的功能:

- (void) inputAccessoryViewDidSelectNext:(FDInputAccessoryView *)view {
    for (UITextField *textField in [self textFieldsArray]) {
        if ([textField isFirstResponder]) {
     textField = [[self textFieldsArray] objectAtIndex:textField.tag + 1];
            [textField becomeFirstResponder];
        }

    }
}

但是这段代码不起作用。我认为使用快速枚举存在问题?

有人可以帮忙吗? 谢谢,亚历克斯。


从 c-had 解决的一些想法:

  1. 为什么要在 textFieldShouldReturn: 中设置 textFieldsArray?这不应该在初始化完成的地方(例如视图控制器的 viewDidLoad)完成吗?问题可能是您的阵列从未实际设置,或者只是部分设置。此外,将设置放在这里意味着它会被一遍又一遍地调用,每次都会改变你的数组并将事情搞砸。
  2. 您的标签减一。您应该从 0 开始分配它们,而不是 1(或考虑 inputAccessoryViewDidSelectNext 的差异:)。如果您的代码正常工作,它将跳过 2 个文本字段,因为第一个字段将返回标签 1,您将跳到 objectAtIndex:2,即第三个字段。
  3. 你不考虑结束。如果您在最后一个字段,递增不会回到开头。

我实际上建议根本不使用标签。相反,在设置时,只需遍历字段,将它们添加到您的数组中。然后,在 inputAccessoryViewDidSelectNext: 中,使用计数器而不是快速枚举来确定您的位置。

【问题讨论】:

  • 1.不要分配或改变您正在枚举的对象,因此创建一个新的文本字段对象(当引用 objectAtIndex 时:textField.tag + 1) 2. 尝试首先退出当前文本字段的第一响应者,然后在第一个上进行下一个响应者
  • 检查并确保您已正确实例化 textFieldArray 并保留它。使用 NSLog 来查看数组是否真的包含某些东西。
  • insertObject: atIndex: 可能是个问题,我试过用过一次,没用...原来在插入之前您需要在该索引处有一个对象...。所以尝试像这样添加对象:addObject:
  • 尝试了你所有的技巧,同事们,但没有任何帮助
  • 唯一的问题是您仅在 textFieldShouldReturn 方法中将对象添加到数组部分,只有在遇到任何特定的文本字段返回或编辑结束时才会调用该方法。到那时它是空的。所以当你遍历数组时,它会为空。

标签: iphone objective-c ios xcode fast-enumeration


【解决方案1】:
  1. 为什么要在textFieldShouldReturn: 中设置textFieldsArray?这不应该在初始化完成的地方完成(例如视图控制器的viewDidLoad)吗?问题可能是您的阵列从未实际设置,或者只是部分设置。此外,将设置放在这里意味着它将被一遍又一遍地调用,每次都会改变你的数组并搞砸。
  2. 您的标签减一。您应该从 0 而不是 1 开始分配它们(或者考虑到 inputAccessoryViewDidSelectNext: 的差异)。如果您的代码正常工作,它将跳过 2 个文本字段,因为第一个字段将返回标签 1,您将跳到 objectAtIndex:2,即第三个字段。
  3. 你不考虑结束。如果您在最后一个字段,递增不会回到开头。

我实际上建议根本不使用标签。相反,在设置时,只需遍历字段,将它们添加到您的数组中。然后,在inputAccessoryViewDidSelectNext: 中,使用计数器而不是快速枚举来确定您的位置。

【讨论】:

  • 非常有用的答案!非常感谢你!我会努力改进你的所有建议,并会在这里写下结果
  • +1。我想你搞定了。 #1是答案。并且#2是非常真实的。 #3 是可选的,如果用户想对最后一个文本字段的 textFieldShouldReturn 执行一些其他操作,则可能不需要。
【解决方案2】:

我建议不要使用任何数组来拥有 textFields,而是从 tableView 的单元格中获取 textFields。

你可以这样做,

用它所在单元格的 indexPath 设置你的 textFields 标签。

然后使用textFieldDidEnd委托,从标签中获取下一个文本字段的单元格,稍后从单元格中获取文本字段并使其成为第一响应者。

如果您可以通过以下方法从FDInputAccessoryView 获取单元格,您也可以在这里进行..

- (void) inputAccessoryViewDidSelectNext:(FDInputAccessoryView *)view`

【讨论】:

  • 从单元格中“获取”文本字段是什么意思?
  • 我的意思是,与其在数组中维护文本字段并从中获取文本字段实例,不如直接从单元格中获取它..
【解决方案3】:

根据文档,“[Fast] 枚举是‘安全的’——枚举器有一个突变保护,因此如果您在枚举期间尝试修改集合,则会引发异常。”这可能就是它不起作用的原因。你可以用一个普通的while循环来完成同样的事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多