2012-05-30 163 views
0

我的應用程序中存在一個大問題,我想知道如何解決它。我在搜索了很多,但我找不到有效的解決方案。這裏是我正在處理的場景。Zombie Objects對於混合ARC和非ARC類的項目的奇怪行爲:EXC_BAD_ACCESS

我有一個非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 
} 

DataSource部分

- (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時,應用程序崩潰EXC_BAD_ACCESS in main方法。這對我來說很奇怪,因爲如果啓用殭屍,我會看到在main中發生的那個錯誤的詳細信息。

我不是很確定的事情是代碼中的autorelease調用,但我認爲如果我不把這些對象放在自動釋放池中,它們會泄漏。

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

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

調查了一下,我發現,如果我在dealloc方法評論[gmGridView release],應用程序停止崩潰。那麼這是什麼意思?如果我不撥打releasegmGridView會泄漏嗎?

你有什麼建議嗎?先謝謝你。

EDIT

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

您是否嘗試在您的項目上運行「分析」?此外,添加「所有例外」斷點可能會有所幫助。 –

+0

謝謝你的回覆。是。對我來說奇怪的是,當殭屍啓用時,不會發生崩潰。 –

+0

可能有外部條件,如內存警告,這會觸發您的異常。每當你運行沒有殭屍程序的應用程序時,是否會發生異常? –

回答

1

Flex_Addicted,

從你的代碼來看,我們正在尋找MRR碼(即非ARC)。如果是ARC,則不能擁有[super dealloc],-release或-autorelease。

這是你的意圖嗎?如果是這樣,那麼你有一個提前釋放。我建議你將這個類轉換成ARC。 ARC和靜態分析器一起會發現早期的重新分配問題並處理它們。

Andrew

+0

+ 1爲您的支持。是的。感謝您的建議。我會嘗試。 –