【问题标题】:ASIHTTPRequest Asynchronous Crash When Changing Views更改视图时 ASIHTTPRequest 异步崩溃
【发布时间】: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 一定有我遗漏的东西,但我不知道它是什么?

谢谢

【问题讨论】:

    标签: iphone objective-c ios cocoa-touch ios4


    【解决方案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。我会做的是:

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

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

        【讨论】:

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