我在ios中遇到内存管理问题。问题是,当我将具有webView的viewController推送到导航堆栈时,并且在加载webview之前单击返回时,我正在获取exec_bad_access。

在“A类”中,我创建一个NewViewController,然后将其推入导航堆栈,然后释放它。所以在这里,我正在释放我的所有权。

A类:

-(void)onButtonClick{
    NewViewController* viewController = [[NewViewController alloc] init];
    [self.navigationController pushViewController: viewController........];
    [viewController release];
}

B类具有一个webView和一个计时器,并实现UIWebViewDelegate。因此,在这里,当webView应该StartLoad时,我正在启动计时器。然后完成加载后,我将其作废。

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文档, Activity 计时器保留对其目标对象的保留。结果,当计时器处于 Activity 状态时,您的控制器无法取消分配。这本身就是架构中的错误,因为从-dealloc方法可以明显看出,您期望在计时器处于 Activity 状态时将视图控制器取消分配。但是对于webview来说,这会引起另一个问题。具体来说,在-webViewDidFinishLoad:方法的中间,您正在取消计时器。这将导致它释放其目标,并且由于它是视图控制器的唯一所有者,因此视图控制器会立即取消分配。

关于objective-c - objective-c -iOS-在执行webViewDidFinishLoad的过程中调用Dealloc,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9068820/

10-10 02:38