asihttprequest 使我的应用程序崩溃
我有一个基于导航的应用程序。按主视图上的按钮,然后我将新视图推送到导航控制器。所有非常基本的东西。
加载新视图时,我执行 ASIHTTPRequest 来获取一些 json 数据,这是图像 url 列表。 然后我执行一个 for 循环,创建一堆 ASIHTTPRequest,将它们添加到队列中,然后运行该队列。
但是,如果我在队列完成之前单击后退按钮,应用程序就会崩溃,该应用程序会显示房屋,假设您选择了错误的房屋,则快速单击返回,在显示任何照片之前,崩溃了。
此帖子 http://groups.google.com/group/asihttprequest/browse_thread/thread /3d4815198aa889b9 很好地解释了我的问题,除了我确实取消了视图上的所有请求并卸载了,将委托设置为 nil 并释放队列。
我还是崩溃了。如果我使用 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]) {
Ad 在少数情况下,它会跳转到我的主循环
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 相比吗?
I have a navigation based app. Press a button on main view, then I push a new view to the navigation controller. All pretty basic stuff.
When the new view is loaded, I do an ASIHTTPRequest to fetch some json data, which is a list of image urls.
Then I do a for loop, create a bunch of ASIHTTPRequests, add them to a queue and then run the queue.
But if I click on the back button before the queue is finished, the app crashes, this app displays houses and lets say you pick the wrong house, click back very quickly, before any photo is displayed, bumm crash.
This thread http://groups.google.com/group/asihttprequest/browse_thread/thread/3d4815198aa889b9 explains my problem real well, except I do cancel all requests on view did unload, set delegate to nil and release the queue.
Still I crash. I crash pretty much every time if I use 3G, but on wifi it is real hard to make it crash, but quite doable.
In almost 80% instances the debugger jumps to this line in ASIHTTPRequest.m
(void)requestReceivedResponseHeaders:(NSMutableDictionary *)newResponseHeaders {
if ([self error] || [self mainRequest]) { return; }
--> if (delegate && [delegate respondsToSelector:didReceiveResponseHeadersSelector]) {
Many many cases it jumps to :
(void)requestReceivedResponseHeaders:(NSMutableDictionary *)newResponseHeaders {
if ([self error] || [self mainRequest]) { return; }
---> if (delegate && [delegate respondsToSelector:didReceiveResponseHeadersSelector]) {
Ad in a handful of instances it goes to my main loop
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;
I am using MBP and MacPro, latest OS X, Xcode 4.0.2 and I test on all apple devices except original iPhones.
I really don't want to re-write my whole app, but is there anything else out there that compares with ASIHTTPRequest ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
尝试在
-viewWillUnload
而不是-viewDidUnload
中取消和取消委托。我怀疑它实际卸载的时间窗口(在调用这两个 UIViewController 方法之间)是你崩溃的时间段。委托已经消失,但您还没有告诉 ASIHTTPRequest 对象。Try cancelling and unsetting the delegate in
-viewWillUnload
rather than-viewDidUnload
. I suspect the window of time in which it's actually unloading (between calling those two UIViewController methods) is the time period when you're crashable. The delegate has gone away, but you haven't told your ASIHTTPRequest object that yet.错误是委托仍然被设置。
我找到了两种方法来解决这个问题。
我认为丑陋的方式是,您创建一个通用委托来处理所有网络流量,并在应用程序首次运行时实例化。我实际上使用了应用程序委托并收听 nsnotification 中心消息。它的工作原理就像一个魅力,应用程序永远不会崩溃,但我认为它不是最佳的。
最好的方法是不设置委托,也不使用“setDidFinishSelector”,而是使用“setCompletionBlock:^”。这仅适用于运行 iOS 4.0 及更高版本的设备,该比例超过 90-95%,并且还在不断增长。这是一个很棒的方法,不会使应用程序崩溃。
The error is that the delegate is still set.
I have found 2 ways to fix this.
The way I consider ugly is that you make a universal delegate that does all network traffic and is instantiated when the app is first run. I actually used the app delegate and listen to nsnotification center messages. It works like a charm, the app never crashes, but I think it is not optimal.
The best way is to not set the delegate and not use "setDidFinishSelector", but instead use "setCompletionBlock:^". This will only work on devices running iOS 4.0 and up, which is more than 90-95% and growing. This is just an awesome way and will not crash the application.
您找不到比 ASIHTTPRequest 更好的东西了,问题在于您如何使用它,而导航上委托消失是一个必须处理的常见问题。
听起来您的问题与正在处理由于用户导航而被破坏的队列的视图控制器有关。我发现解决这些问题的最佳方法是拥有一个中央模型类来处理我的所有通信,并在整个应用程序生命周期中保留该类。
这样,当代表意外消失时,您就不会遇到无法解释的崩溃。
选项 2
另一种方法是禁用用户导航,直到网络操作完成。在整个屏幕上放置一个模态视图,显示 uiactivityview,以便用户知道他们的操作被阻止。然后,当数据到达时,您可以淡出模式视图。如果你用渐变很好地设计屏幕,使背景稍微变暗,那么看起来还可以。但这并不是最好的方法 - 您应该修复委托擅离职守的问题。
我们可能需要查看更多与队列创建、销毁等相关的代码才能找到确切的问题。
You won't find anything better that ASIHTTPRequest, the problem will be how you are using it and vanishing delegates on navigation are a common problem to have to deal with.
It sounds like your problem relates to the viewcontroller that is handling the queue being destroyed due to user navigation. I find the best way of solving these issues is to have a central model class that handles all my communications and keep that class throughout the application lifecycle.
That way you don't get unexplained crashes when delegates have vanished unexpectedly.
Option 2
Another approach can be to disable user navigation until the network operation completes. Put a modal view over the entire screen that shows a uiactivityview so the user knows their actions are being blocked. Then you can fade the modal view off when the data has arrived. If you design the screen nicely with a gradient so the background just dims a bit, this can look OK. But it's not really the best approach - you should fix the delegate AWOL instead.
We probably need to see more of the code relating to the queue creation, destruction etc to find the exact issue.
您的应用程序委托可以拥有一组请求队列。该数组独立于导航控制器堆栈和关联视图的状态。您可以将请求添加到应用程序委托队列实例,或者停止所有请求并清空队列等,而不是将请求绑定到导航堆栈中的视图控制器,并且必须执行 UI 技巧来阻止弹出回父视图。
Your application delegate can own an array of request queues. The array lives independent of the state of the navigation controller stack and associated views. Instead of tying requests to a view controller in the nav stack, and having to do UI tricks to block popping back to a parent view, you could add requests to an app delegate queue instance, or stop all requests and empty the queue, etc.