在iOS ARC中,我的递归函数使用EXC_BAD_ACCESS崩溃了应用程序

时间:2014-08-25 07:14:01

标签: ios objective-c recursion automatic-ref-counting exc-bad-access

以下代码在ARC模式下生成崩溃:

MxTextField.m

+enableAllTextFields:(BOOL)enable InViews:(__weak UIView*) view
{

   @try
   {
      NSArray* textFields = view.subViews;

      for(int idx = 0; idx < textFields.count; idx++)
      {
         __weak UIView* view = [textFields objectAtIndex:idx];

         if(view.subViews.count > 0)
            [MxTextField enableAllTextFields:enable InView:view];
         else
            NSLog(@"No SubViews");

         if([view class] == [MxTextField class])
            [(MxTextField*) view setEnabled:enable];
      }

   }
   @catch(NSException exception)
   {
      NSLog(@"%s : %@",__func__,exception);
   }

}

执行此函数之后的某些循环它通过在函数末尾显示EXC_BAD_ACCESS的断点来崩溃。任何人都可以帮我解决这个实现中出了什么问题吗?

任何帮助都会感激不尽。

2 个答案:

答案 0 :(得分:1)

问题可能是迭代采用的方法,而try-catch也不是一个好习惯,使用快速枚举可以获得更快更可靠的结果。以下代码可以解决您的问题

+(void)enableAllTextField:(BOOL)enable inView:(UIView *)contrainerView
{
    for (UIView *subview in contrainerView.subviews) {
        if(subview.subviews.count>0)
             [MxTextField enableAllTextField:enable inView:subview];
        else if ([subview isKindOfClass:[MxTextField class]]) {
             MxTextField *textField = (MxTextField *)subview;
             [textField setEnabled:enable];
        }
    }
}

答案 1 :(得分:1)

抛开许多其他问题,我可以从发布的代码中看到崩溃的唯一原因是你的方法应该返回一个对象但不会这样做。

说明:虽然在Objective-C中省略返回类型并不常见,但这是完全合法的。这意味着该方法返回一个id为。

的对象

由于您的方法缺少return语句,因此返回的值未定义。这会使ARC感到困惑,并可能使其自动释放返回寄存器中的随机值,最终会导致崩溃。

以下是您的方法的正确版本:

+ (void)forAllTextFieldsIn:(UIView *)view setEnabled:(BOOL)enabled
{
    if ([view isKindOfClass:[MxTextField class]])
        [(MxTextField *)view setEnabled:enabled];

    for (UIView *subview in view.subviews)
        [self forAllTextFieldsIn:subview setEnabled:enabled];
}