Zombie Objects对于混合使用ARC和NON-ARC类的项目的奇怪行为:EXC_BAD_ACCESS

时间:2012-05-30 09:46:16

标签: objective-c ios automatic-ref-counting nszombie gmgridview

我的应用程序存在很大问题,我想知道如何解决它。我在SO中搜索了很多,但我找不到有效的解决方案。这是我正在研究的场景。

我有一个NON-ARC应用程序,我在其中使用了一堆ARC类。这些类属于GMGridView。这些类已使用-fobjc-arc指令添加到项目中。

这是我正在使用的代码(为了简单起见,我只添加了关键部分)。

内存管理部分

- (void)dealloc
{
    [gmGridView setActionDelegate:nil];
    [gmGridView setDataSource:nil];
    [gmGridView release];    

    [super dealloc];
}

ViewDidLoad部分

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSInteger topBottomSpacing = 20;
    NSInteger leftRifghtSpacing = 75;
    NSInteger itemSpacing = 5;

    UIView* mainView = [self view];

    GMGridView* gridView = [[[GMGridView alloc] initWithFrame:mainView.bounds] autorelease];    
    gridView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    gridView.backgroundColor = [UIColor clearColor];   
    gridView.style = GMGridViewStyleSwap;
    gridView.itemSpacing = itemSpacing;
    gridView.minEdgeInsets = UIEdgeInsetsMake(topBottomSpacing, leftRifghtSpacing, topBottomSpacing, leftRifghtSpacing);
    gridView.centerGrid = NO;
    gridView.actionDelegate = self;
    gridView.dataSource = self;    
    [mainView addSubview:gridView];

    [self setGmGridView:gridView]; // retain policy
}

数据源部分

- (GMGridViewCell *)GMGridView:(GMGridView *)gridView cellForItemAtIndex:(NSInteger)index
{
    CGSize size = [self GMGridView:gridView sizeForItemsInInterfaceOrientation:[[UIApplication sharedApplication] statusBarOrientation]];

    GMGridViewCell *cell = [gridView dequeueReusableCell];    
    if (!cell) {

        cell = [[[GMGridViewCell alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height)] autorelease];

        InternalView *view = [[[InternalView alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height)] autorelease];
        cell.contentView = view;
    }

    return cell;
}

当我使用Zombie Objects时,该应用程序运行良好。没有错误。但是,当我禁用Zombie Objects时,应用程序会在main方法中崩溃 EXC_BAD_ACCESS 。这对我来说很奇怪,因为如果启用Zombies,我会在main中看到该错误的详细信息。

我不太确定的是代码中的autorelease调用,但我认为如果我不将对象放在自动释放池中,它们就会泄漏。

GMGridView* gridView = [[[GMGridView alloc] initWithFrame:mainView.bounds] autorelease];

cell = [[[GMGridViewCell alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height)] autorelease];

稍微调查一下,我发现如果我在[gmGridView release]方法中评论dealloc,该应用就会停止崩溃。那么这是什么意思?如果我不致电releasegmGridView会泄漏吗?

你有什么建议吗?提前谢谢。

修改

我在- (GMGridViewCell *)GMGridView:(GMGridView *)gridView cellForItemAtIndex:(NSInteger)index方法中添加了一些代码。我忘了第一次添加它。

dealloc InternalView(类型UIView)的- (void)dealloc { [addButton release]; // it's added to self addSubview, it has also a retain policy [imageView release]; // it's added to detView addSubview, it has also a retain policy [detView release]; // it's added to self addSubview, it has also a retain policy [super dealloc]; } 方法似乎是问题的根源。这是代码。

[detView release]

评论{{1}}时,崩溃就会消失。

1 个答案:

答案 0 :(得分:1)

Flex_Addicted,

从您的代码判断,我们正在查看MRR代码(即非ARC)。如果它是ARC,你就不能拥有[super dealloc],-release还是-autorelease。

这是你想要的吗?如果是这样,那么你有一个早期的释放。我建议您将此类转换为ARC。 ARC和静态分析器一起发现早期的释放问题并处理它们。

安德鲁