Разработка iPhone/iPod touch приложений: обNULLяйте делегатов

xcodeПросто обязан написать об этом:)

Сегодня выплыла проблема случайных крешей приложения, примерно следующего плана


EXC_BAD_ACCESS

objc_msgSend + 24
-[UIWebView webView:resource:didFinishLoadingFromDataSource:] + 80
-[UIWebViewWebViewDelegate webView:resource:didFinishLoadingFromDataSource:] + 36

Проверка на двойное и преждевременное освобождение объектов ничего не дала. То есть с памятью проблем небыло. Проблема была в чем-то другом. Судя по call-Tree, было сделано предположение, что UIWebView, вызывает метод делегата, который уже был удален из памяти. По сути, такого произойти не могло, так как обычно такими делегатами являются UIViewController’ы, которые в методе dealloc вызывают [webView release].

Но! Как оказалось, этого совсем недостаточно. Итак – решение проблемы. В методе dealloc, либо в любом месте, где вы прекращаете использовать объект, у которого вы прописаны делегатом, делайте следующее [webView setDelegate:nil]. В таком случае, даже если объект будет слать какие-то сообщения делегату, то приложение не будет вылетать с ошибкой.

Вывод:Как уже было сказано выше – всегда “обNULLяйте” делегата объекта. Ну, и пример кода соотвественно.


// ViewItemController.h
@interface ViewItemController : UIViewController < UIWebViewDelegate> {
   UIWebView *webView;
}
@property(nonatomic, retain) IBOutlet UIVebView * webView;
@end

// ViewItemController.m
-(void)viewDidLoad {
 [[self webView] setDelegate:self]
}

//
// На самом деле вполне "понятно", что после [webView release],
// совсем не факт, что webView уничтожится, ведь retainCount
// может быть все еще больше 0. Но для понимания этого
// нужно задуматься, а на это время не всегда хватает ;)
-(void) dealloc {
 [webView setDelegate:nil];
 [webview release];
 [super dealloc];
}

Пока нет комментариев.

Оставить комментарий