更改视图时 ASIHTTPRequest 异步崩溃

Posted

技术标签:

【中文标题】更改视图时 ASIHTTPRequest 异步崩溃【英文标题】:ASIHTTPRequest Asynchronous Crash When Changing Views 【发布时间】:2011-06-10 13:35:53 【问题描述】:

我正在使用 ASIHttpRequest 从 xml 文件中接收数据。但是,在异步请求期间,只要我更改视图(使用导航控制器返回上一个视图),应用程序就会崩溃,并在 main.m 上显示 EXC_BAD_ACCESS

这只发生在发出请求时。

下面是我的代码:

-(void)ProcessXML

    //Set url from string to url
    NSURL *theurl = [NSURL URLWithString:@"http://twitter.com/statuses/user_timeline/2smssupport.xml"];

    asirequest = [ASIHTTPRequest requestWithURL:theurl];
    [asirequest setDelegate:self];
    [asirequest startAsynchronous];




- (void)requestFinished:(ASIHTTPRequest *)request



    NSLog(@"Saving to Defaults");
    NSData *responseData = [request responseData];
    xmlSaved = responseData;

    prefs = [NSUserDefaults standardUserDefaults];
    [prefs setObject:responseData forKey:@"xmlDownload"];
    rssParser = [[RssParser alloc] loadXMLbyURL:xmlSaved];
    [self.tableView reloadData];
    NSLog(@"%@",[prefs dataForKey:@"xmlDownload"]);


Process XML 方法触发请求,然后接收到的数据在 RequestFinished 中处理。

ASIHTTPRequest 一定有我遗漏的东西,但我不知道它是什么?

谢谢

【问题讨论】:

【参考方案1】:

这段代码应该可以修复它:

    -(void) viewWillDisappear:(BOOL)animated 
        [super viewWillDisappear:animated];
        [request clearDelegatesAndCancel]
     

【讨论】:

【参考方案2】:

如果视图正在释放,那么您在请求中设置的委托现在无效。确保在视图 dealloc 上将委托设置为 nil 并停止请求。

【讨论】:

我该怎么做?我已在 dealloc 中将 asirequest 设置为 nil,但它仍然崩溃 [asirequest setDelegate:nil]; 我收回了它,它确实有效......但现在它在 asihttprequest 类的某处出现 EXC_BAD_ACCESS 错误 开启僵尸 - 在可执行参数中将 NSZombieEnabled 添加为 YES 并查看它中断的行,它将显示正在过度释放的对象...【参考方案3】:

asirequest 对象没有被保留在任何地方,所以它在ProcessXML 返回后被释放。

【讨论】:

即使视图改变了?请求发生在看起来是后台线程的地方。 它是自保留的,你不需要保留或释放它。 @Simon Lee,你为什么这么说?我刚刚检查了文档和源代码,我觉得它不像。 我的意思是请求是在主线程上发出的,但一切都在后台工作。这一直难倒我,所以我通常只使用同步请求。我现在收到以下错误:尝试使用不在框架中的块创建 USE_BLOCK_IN_FRAME 变量。 ||在 dealloc 中分配 [asirequest setDelegate:nil] 会导致应用立即崩溃 - (IBAction)grabURLInBackground:(id)sender NSURL *url = [NSURL URLWithString:@"allseeing-i.com"]; ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url]; [request setDelegate:self] ; [请求启动异步]; 【参考方案4】:

NSZombieEnabled 对你有很大帮助。您可以判断是哪个对象导致了 EXC_BAD_ACCESS。

【讨论】:

【参考方案5】:

您是否在离开当前视图时释放ASIHTTPRequest 对象?我的猜测是在您的视图控制器被释放后调用委托方法。

--

@Simon 是正确的,您确实需要将委托设置为 nil。我会做的是:

    在您的类中创建一个ASIHTTPRequest 属性并在您的ProcessXML 方法中设置该属性。这简化了内存管理并确保请求对象在您需要时始终存在。 在您的dealloc 方法和requestFinished 方法中,将请求委托设置为nil 并设置self.request = nil;

至少,您应该在 requestFinished 方法中将委托设置为 nil,但是如果您在返回之前离开此视图控制器,则需要记住停止运行您的请求,因此将其设置为 nil在dealloc 方法中也是如此。

【讨论】:

这可能是正确的,那么我将如何解决这个问题呢? iPhone 上的内存分配让我有些困惑 它是自保留的,你不需要保留或释放它。但根据我的回答,您需要将委托设置为 nil。 那我需要在哪里将代理设置为零?在交易中? @Simon - 更常见的术语是“自动发布”。当自动释放池在当前运行循环结束时耗尽时,它被标记为释放。 “自我保持”意味着它可以在任意时间内保持自己的存在,而它不能。 我可以随时调用 [self retain] 然后 [self release]。我很清楚自动发布...查看我的简历 ;)

以上是关于更改视图时 ASIHTTPRequest 异步崩溃的主要内容,如果未能解决你的问题,请参考以下文章

iPhone ASIHTTPRequest 从 requestFinished 方法中异步提取响应

异步添加图像 - ASIHTTPRequest

使用导致崩溃的搜索结果更新表视图

ASIHTTPRequest 在 iOS 3.1.3 上崩溃

ASIHTTPRequest取消异步请求

没有视图的片段在配置更改时崩溃