包含对象的NSMutableArray EXC_BAD_ACCESS

时间:2011-03-20 09:20:24

标签: iphone objective-c memory-management exc-bad-access

我有一个实现NSMutableArray对象的类。现在,当手机进入横向模式时,NSMutableArray中的所有对象都会从视图中删除(但不会从NSMutableArray中删除),然后当手机回到纵向模式时,我将NSMutableArray中包含的所有对象放入视图,但是当我尝试访问我收到的第一个对象时:EXC_BAD_ACCESS。

这是我的代码:

- (void) setObjects:(BOOL)hidden andWindow:(UIWindow *)win andTxt:(UITextView *)txt andTarget:(id) target {
    //view
    key = [win.subviews objectAtIndex:0];
    key.hidden = hidden;
    buttons = [[NSMutableArray alloc] initWithCapacity:1]; //my array
    txtsms = txt;
        [...]
}

- (void) addButton:(button *)but {
    [key addSubview:[but returnButton]];
    [buttons addObject:but];
    [but release];
}

- (void) hiddenAllKey {
    for (UIView *subview in [key subviews])
        if ((subview.tag <= startSpecialPunctuation+1)&&(subview.tag >= spaceButton+1)) 
            [subview removeFromSuperview];
}

- (void) showAllKey {   
    for(int i = 0; i < [buttons count]; ++i)
             [key addSubview:[[buttons objectAtIndex:i] returnButton]]; //this is the problem :|
}

2 个答案:

答案 0 :(得分:3)

正如Joe Blow所说,这是错误的:

- (void) addButton:(button *)but {
    [key addSubview:[but returnButton]];
    [buttons addObject:but];
    [but release];
}

but不应该在该方法中发布。同样,这在我心中引起了恐惧:

- (void) setObjects:(BOOL)hidden andWindow:(UIWindow *)win andTxt:(UITextView *)txt andTarget:(id) target {
    //view
    key = [win.subviews objectAtIndex:0];
    key.hidden = hidden;
    buttons = [[NSMutableArray alloc] initWithCapacity:1]; //my array

你在哪里发布buttons?您的应用只会调用一次该方法吗?如果没有,那么你将泄漏buttons

在您的代码上尝试build and analyze,修复它识别出的任何问题。如果它仍然崩溃,请发布崩溃的回溯

答案 1 :(得分:1)

- (void) hiddenAllKey {
    for (UIView *subview in [key subviews])
        if ((subview.tag <= startSpecialPunctuation+1)&&(subview.tag >= spaceButton+1)) 
            [subview removeFromSuperview];
}

这也是一个微妙的错误。您正在从使用快速枚举枚举的列表中删除元素。它可以(应该)容易失败。

以前,我在UIView上编写了一个类别来删除所有内容,这可以通过一个简单的while循环来实现。现在,你正在尝试做什么...你可以做一个for循环,你自己管理迭代索引,即当你不删除时,你增加,否则你保持不变。

编辑:建议解决方案:

for (int idx = 0; idx < [[key subviews] count]; )
{
    UIView *subview = [[key subviews] objectAtIndex: idx];
    if ((subview.tag <= startSpecialPunctuation + 1) && (subview.tag >= spaceButton + 1))
    {
        [subview removeFromSuperview];
    }
    else
    {
        idx++;
    }
}