2011-04-18 82 views
9

我有一个基于导航的应用程序。按主视图上的按钮,然后将新视图推送到导航控制器。所有非常基本的东西。asihttprequest崩溃我的应用程序

加载新视图时,我执行一个ASIHTTPRequest来获取一些json数据,这是一个图像url的列表。 然后我做一个for循环,创建一堆ASIHTTPRequests,将它们添加到队列中,然后运行队列。

但是,如果在队列结束之前点击后退按钮,应用程序崩溃,此应用程序会显示房屋,并可以说您选择了错误的房屋,在显示任何照片之前快速点击,并发生撞击。

此线程http://groups.google.com/group/asihttprequest/browse_thread/thread/3d4815198aa889b9解释我的问题真的很好,除非我取消所有视图请求卸载,将委托设置为零并释放队列。

我仍然崩溃。如果我使用3G,每次都会崩溃,但在WiFi上真的很难让它崩溃,但相当可行。

在几乎80%的情况下,调试器跳转到该行ASIHTTPRequest.m

(void)requestReceivedResponseHeaders:(NSMutableDictionary *)newResponseHeaders { 
    if ([self error] || [self mainRequest]) { return; } 
--> if (delegate && [delegate respondsToSelector:didReceiveResponseHeadersSelector]) { 

许多许多情况下,跳转到:

(void)requestReceivedResponseHeaders:(NSMutableDictionary *)newResponseHeaders { 
    if ([self error] || [self mainRequest]) { return; }  
---> if (delegate && [delegate respondsToSelector:didReceiveResponseHeadersSelector]) { 

广告的情况下,极少数是去我主循环

int main(int argc, char *argv[]) { 
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 
--> int retVal = UIApplicationMain(argc, argv, nil, nil); with SIGBART error [pool release]; return retVal; 

我使用MBP和MacPro,最新的OS X,Xcode 4.0.2和我测试所有除原装iPhone之外的其他设备。

我真的不想重写我的整个应用程序,但是还有什么与ASIHTTPRequest相比?

回答

3

错误是委托仍然设置。

我发现有2种方法可以解决这个问题。

我认为丑陋的一种方式是,您创建一个通用委托,执行所有网络通信并在应用第一次运行时实例化。我实际上使用了应用程序委托并收听nsnotification中心消息。它的作用就像一个魅力,应用程序从不崩溃,但我认为这不是最佳。

最好的方法是不设置委托,不使用“setDidFinishSelector”,而是使用“setCompletionBlock:^”。这只适用于运行iOS 4.0及更高版本的设备,这个数量超过了90-95%,并且在不断增长。这只是一种非常棒的方式,不会使应用程序崩溃。

+0

很好的回答,它的工作 – KsK 2013-08-26 07:27:31

+0

使用第二种方法实际上有效。谢谢。我被困在这个上太久了。干杯。 – 2014-02-11 09:23:51

3

你不会找到任何更好的ASIHTTPRequest,问题将是你如何使用它,消除导航代表是一个常见的问题,必须处理。

这听起来像你的问题涉及到处理由于用户导航而被销毁的队列的视图控制器。我发现解决这些问题的最好方法是拥有一个中央模型类,它处理我所有的通信并在整个应用生命周期中保持这个类。

这样,当代表意外消失时,您不会得到无法解释的崩溃。

选项2

另一种方法可以是,直到网络操作完成来禁用用户导航。在显示uiactivityview的整个屏幕上放置一个模式视图,以便用户知道他们的操作被阻止。然后,您可以在数据到达时淡出模态视图。如果你用渐变很好地设计屏幕,使背景变暗一点,这可以看起来不错。但它不是最好的方法 - 你应该修复委托AWOL。

我们可能需要查看更多有关队列创建,销毁等的代码才能找到确切的问题。

+0

这样的中心阶层会是什么样子? – 2011-04-18 18:20:54

+0

我想中心阶层将是一个单身人士。 – 2011-08-12 16:07:09

+0

可以是单例或仅由实例化一次并由应用程序委托保留的类。 – Roger 2011-08-12 17:23:30

1

您的应用程序委托可以拥有一个请求队列数组。数组独立于导航控制器堆栈和相关视图的状态。您可以将请求添加到应用程序委托队列实例,或停止所有请求并清空队列等,而不必将请求绑定到导航堆栈中的视图控制器,并且必须执行UI技巧来阻止弹出回到父视图。

+0

你能解释我将如何去做这样一个单例委托,或者我会只使用App委托?你的想法听起来很有趣,但我无法完全想象它。 – 2011-04-18 18:20:21

+0

只需使用应用程序代理。或者你可以创建一个由应用程序委托拥有的单例。你可以搜索“可可单身人士”了解更多信息。 – 2011-04-18 20:40:21

12

尝试取消并取消设置-viewWillUnload中的代理人而不是-viewDidUnload。我怀疑它实际上卸载的时间窗口(在调用这两个UIViewController方法之间)是可以被破坏的时间段。代表已经离开,但你还没有告诉你的ASIHTTPRequest对象。

+6

在viewWillDissapear,这似乎已经做到了,至少我无法让它崩溃。我做了,但添加了以下代码,只是为了确保: - (void)viewWillDisappear:(BOOL)animated {super viewWillDisappear:animated]; (队列操作中的ASIHTTPRequest *请求){ [req clearDelegatesAndCancel]; [req setDelegate:nil]; [req setDidFailSelector:nil]; [req setDidFinishSelector:nil]; } [queue cancelAllOperations]; [queue setDelegate:nil]; } – 2011-04-18 18:18:18