sendSynchronousRequest在慢速网络连接上崩溃了吗?

时间:2013-05-16 04:59:16

标签: objective-c nsurlconnection

我在sendSynchronousRequest上使用NSURLConnection方法从服务器加载图像。它在网络连接速度很快时工作正常,但在连接速度很慢时崩溃我的应用程序。我做错了什么?

[postBody appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];            
[postBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"image\";filename=\"%@.jpg\"\r\n",uploadImageName] dataUsingEncoding:NSUTF8StringEncoding]];            
[postBody appendData:[[NSString stringWithString:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[NSData dataWithData:UIImageJPEGRepresentation(Obj1.thumbImage, 0.5)]];
[postBody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
[postRequest setHTTPBody:postBody];

NSData *returndata=[NSURLConnection sendSynchronousRequest:postRequest returningResponse:nil error:nil];
NSString *string=[[NSString alloc]initWithData:returndata encoding:NSUTF8StringEncoding];

NSError *error; 
NSString *path;
NSData *imageData;

if (error != nil && [string isEqualToString:@"success"]) {
    //doing other work
}

我使用后台线程来运行所有这些代码。当我在网络连接缓慢时上传更多图像时,应用程序崩溃。

2 个答案:

答案 0 :(得分:2)

可悲的是,我没有在代码片段中看到任何可能导致崩溃的明显内容。在这个答案的最后,我提供了我所做的代码示例,所以也许你可以将它与你的交叉引用。

有几点想法:

  1. 你说这适用于快速连接,但不能缓慢连接。这是从主线程运行同步查询的症状。如果您不小心从主队列执行了此同步调用,则在缓慢连接时,监视程序进程可能会终止您的应用程序。只要主线程没有响应,它就会这样做。

    所以使用异步调用(正如你在其他问题中所追求的那样)或确保在后台队列中发生这种情况。

    顺便说一句,你说你使用performSelectorInBackground将其提交给后台线程。现在大多数人都会使用GCD或NSOperationQueue。请参阅Concurrency Programming Guide

  2. 一般情况下,如果有异常,我会要求您检查一些变量:

    • 您没有向我们展示alloc的{​​{1}} / init。如果是postDatanil而不是NSData,则可能会出现例外情况。

    • 您应该确保NSMutableData不是Obj1.thumbImage。这也可能导致异常。

    坦率地说,如果这是在快速连接而不是慢速连接,那么问题就不太可能在这些变量的基本设置中,而是你是否在其他地方异步更新它们(而不是同步你的更新) 线程编程指南Synchronization部分或并发编程指南中的Eliminating Lock-Based Code的队列。在编写线程安全代码时,需要注意同步更改,在某些情况下,连接速度会影响行为。

  3. 如果这两点无法解决您的问题,那么我们真的需要深入了解您的异常。毋庸置疑,每当您发布有关异常的任何问题时,您必须:

    • 告诉我们什么是例外

    • 识别导致异常的行;你可以通过

      来做到这一点
      • 查看堆栈跟踪以缩小问题的根源;

      • 试试adding an exception breakpoint;有时,这将识别导致异常的精确线。

      • 如果这不起作用,请尝试单步调试调试器中的代码。

      • 诊断问题的最不优雅的方法是添加一堆nil语句,这样你就可以弄清楚崩溃前代码的程度,以及各种变量是你期望的值。 / p>

  4. 如果你原谅观察,我感谢你试图让我们免于太多的代码(有时人们会发布大量不相关的代码;所以感谢你们放弃了我们),你们通常不会分享不够的代码。十分之九,人们所遭受的错误/异常是一些简单变量的结果尚未设置为您认为它具有的(例如未初始化等)。因此,您需要包含稍微更完整的代码示例,或者您的代码段应包含证明值有效的NSLogNSLogif语句。

    例如,您可能想要输入

    assert

    这可以确保自己在后台线程上运行。您可能还希望在访问时记录if ([NSThread isMainThread]) { NSLog(@"%s: should not be on main thread!!!", __FUNCTION__); } Obj1.thumbImage

    我已经看到了你的一些问题,你(a)发布一些简单的代码,(b)告诉我们它在这个片段中的某个地方崩溃(但不是精确到哪里)和(c)向我们保证价值通过非常简单的代码片段都是有效的(即使代码片段没有说明)。简单的现实,通常不是所有这三个条件都可以同时成立。当人们发布崩溃时,问题就像在代码本身中传递给违规代码的变量一样。

  5. 一些不相关的观点:

    1. 另外,在postBody中,您为sendSynchronousRequest指定了nil。如果API为您提供诊断错误成功或失败的机会,您应该利用它。

    2. 使用error确实是最糟糕的情况,会导致严重的数据丢失。如果人性化,请返回UIImageJPEGRepresentation的来源(如何创建?UIImage?)。如果你不能这样做,可以考虑NSData,因为它仍然享受压缩,但数据丢失更少。有时你必须做UIImagePNGRepresentation,但认为它是最后的工具。

    3. 如果您的服务器只返回“成功”文本字符串,那么我想这就是您所能做的。如果可能,最好是您可以对服务器进行编程以返回JSON响应,您可以轻松地为不同类型的错误/响应使用/解析不同的返回代码。

    4. 无论如何,这是一个有效的上传例程:

      UIImageJPEGRepresentation

答案 1 :(得分:0)

追踪这个...

添加异常断点。这样就会在发生异常的行上停止调试器。

后台线程没有自己的异常处理程序,因此它们会生成一个信号并导致进程崩溃。所以你可以添加自己的东西,特别是这样的,系统调用正在生成异常,你没有一个好的方法来阻止它。

@try{

    NSData *returndata=[NSURLConnection sendSynchronousRequest:postRequest returningResponse:nil error:nil];
    NSString *string=[[NSString alloc]initWithData:returndata encoding:NSUTF8StringEncoding];

}

@catch(NSException *e)
{
    NSLog(@"caught exception: %@",e);
    //you could also iterate over: - (NSArray *)callStackSymbols NS_AVAILABLE(10_6, 4_0);
}