Разработка iPhone/iPod touch приложений: обNULLяйте делегатов
Просто обязан написать об этом:)
Сегодня выплыла проблема случайных крешей приложения, примерно следующего плана
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];
}














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