简体   繁体   English

包含对象的NSMutableArray EXC_BAD_ACCESS

[英]NSMutableArray EXC_BAD_ACCESS on contained objects

I have a class where I implement a NSMutableArray of objects. 我有一个类,我实现了一个NSMutableArray对象。 Now, when the phone goes into landscape mode, all of the objects in the NSMutableArray are deleted from the view (but not from the NSMutableArray), then when the phone goes back to portrait mode, I put all the objects contained in the NSMutableArray into the view, but when I try to access the first object I receive: EXC_BAD_ACCESS. 现在,当手机进入横向模式时,NSMutableArray中的所有对象都会从视图中删除(但不会从NSMutableArray中删除),然后当手机回到纵向模式时,我将NSMutableArray中包含的所有对象放入视图,但是当我尝试访问我收到的第一个对象时:EXC_BAD_ACCESS。

This is my code: 这是我的代码:

- (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 :|
}

As Joe Blow said, this is wrong: 正如Joe Blow所说,这是错误的:

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

but should not be released in that method. but不应该以该方法发布。 Similarly, this strikes fear in my heart: 同样,这在我心中引起了恐惧:

- (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

Where do you release buttons ? 你在哪里发布buttons Does your app only ever call that method once? 您的应用只会调用一次该方法吗? If not, then you'll be leaking buttons . 如果没有,那么你将会泄漏buttons

Try build and analyze on your code, fixing any problems that it identifies. 尝试build and analyze您的代码,修复它识别的任何问题。 If it still crashes, post the backtrace of the crash 如果它仍然崩溃,请发布崩溃的回溯

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

This is subtly wrong too. 这也是一个微妙的错误。 You are removing elements from a list you are enumerating using fast enumeration. 您正在从使用快速枚举枚举的列表中删除元素。 It can (should) fail easily. 它可以(应该)容易失败。

Previously, I've written a category on UIView to do a remove all, that was doable with a simple while loop. 以前,我已经在UIView上编写了一个类别来删除所有内容,这可以通过简单的while循环来实现。 Now, what you're trying to do... you might do a for loop where you manage the iterated index yourself, ie when you don't remove, you increment, else you keep it the same. 现在,你正在尝试做什么......你可能会做一个for循环,你自己管理迭代索引,即当你不删除时,你增加,否则你保持相同。

EDIT: suggestion of solution: 编辑:建议解决方案:

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++;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM