0

У меня большая проблема в моем приложении, и мне интересно, как его решить. Я много искал в SO, но я не могу найти правильное решение. Здесь сценарий, над которым я работаю.Странное поведение с объектами Zombie для проекта, который смешивает классы ARC и NON-ARC: EXC_BAD_ACCESS

У меня есть приложение 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 
} 

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, приложение работает хорошо. Нет ошибок. Но когда я отключу объекты Zombie, приложение выдает EXC_BAD_ACCESS в методе main. Это довольно странно для меня, поскольку, если Zombies включены, я бы увидел деталь этой ошибки, которая происходит в main.

То, что я не совсем уверен, вызывает в коде вызовы , но я думаю, что если я не положу объекты в пул автономии, они будут течь.

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

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

Исследуя немного, я обнаружил, что если я комментирую [gmGridView release] в dealloc методе, приложение останавливается врезаться. Так что это значит? Если я не позвоню release, будет ли утечка gmGridView?

Есть ли у вас какие-либо предложения? Заранее спасибо.

EDIT

Я добавил код в - (GMGridViewCell *)GMGridView:(GMGridView *)gridView cellForItemAtIndex:(NSInteger)index методом. Я забыл добавить его в первый раз.

Метод deallocInternalView (типа 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 для вашей поддержки. Да. Спасибо за совет. Я попробую. –