我在 ios 中遇到内存管理问题。问题是,当我将一个具有 webView 的 viewController 推送到导航堆栈时,当我在加载 webview 之前单击返回时,我得到了 exec_bad_access。
在“A 类”中,我创建一个新的 ViewController,然后将其推送到导航堆栈,然后释放它。因此,我在释放它时放弃了我的所有权。
A类:
-(void)onButtonClick{
NewViewController* viewController = [[NewViewController alloc] init];
[self.navigationController pushViewController: viewController........];
[viewController release];
}
B 类有一个 webView 和一个计时器,并实现 UIWebViewDelegate。因此,当 webView shouldStartLoad 时,我正在启动计时器。然后当它加载完成时,我将使其无效。
Class B:
@interface NewViewController : UIViewController <UIWebViewDelegate>
NSTimer* timer
......
@property(nonatomic, retain) IBOutlet UIWebView* webView;
@end
@implementation
-(void)viewDidLoad{
[super viewDidLoad];
[webView loadRequest:someRequest];
}
.....
.....
-(void)dealloc{
[self makeTimerNil];
[self.webView stoploading];
self.webView.delegate = nil;
[self.webView release];
self.webView = nil;
.....
[super dealloc];
}
-(void)resetTimer{
[self makeTimerNil];
//timer will retain target - self
timer = [NSTimer scheduledTimerWithTimeInterval:kNetworkTimeOut target:self selector:@selector(networkTimedOut) userInfo:nil repeats:NO];
}
-(void)makeTimerNil{
if([timer isValid]){
[timer invalidate];
timer = nil;
}
}
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
[self resetTimer];
......
return YES;
}
-(void)webViewDidFinishLoad:(UIWebView *)webView{
//NO Exception. Can access self
[self anotherMethod];
//timer releases retained target -self
[self makeTimerNil];
//Exception self has been deallocated
[self anotherMethod];
}
@end
但问题是,当 webView 加载时,如果我单击导航栏上的后退按钮, newViewController 就会被释放,这很好。但这是在 webViewDidFinishLoad 执行过程中发生的。为什么在 webViewDidFinishLoad 执行过程中调用 dealloc?它们不是在同一个线程(主 - UI 线程)上运行吗?
关于如何解决这个问题有什么想法吗?
你的问题绝对是计时器。根据 NSTimer 文档,活动计时器在其目标对象上保留保留。结果,你的控制器cannot当计时器处于活动状态时被释放。这本身就是你的架构中的一个错误,因为从你的-dealloc
方法很明显你期望视图控制器在计时器处于活动状态时被释放。但就 webview 而言,它导致了另一个问题。具体来说,在你的中间-webViewDidFinishLoad:
取消计时器的方法。这会导致它释放其目标,并且由于它是视图控制器的唯一所有者,因此视图控制器立即释放。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)