在上传所有数据之后和connectionDidFinishLoading之前,NSURLConnection崩溃

时间:2014-04-19 12:47:46

标签: ios objective-c

我有一个上传者类(mediaUploader),它获得NSData并将其上传到特定服务器。此类不是单例并且可以实例化(尽管实现了单例QueueManager类以将每个上载请求分派给mediaUploader的对象)。 问题是这个实现现在已经工作了一个多月了,但是当我连续上传2个文件时,第一个文件上传时没有任何问题,connectionDidFinishLoading委托方法NSURLConnection被调用它。但第二个上传到100%(我知道因为我在connection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite:跟踪上传的进度),但没有转到connectionDidFinish方法,也没有转到connectionDidFail。 之后,connection:didReceiveResponse:connection:didReceiveData:也被调用(正常上传的正常转换也会这样做)但在这两个之后通常会调用didFinishLoading方法,而不是我的应用程序崩溃。 我的堆栈跟踪如下:

#0  0x00000000 in 0x00000000 ()
#1  0x3186ffc2 in __65-[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:]_block_invoke ()
#2  0x3186ff06 in -[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:] ()
#3  0x3186fe20 in -[NSURLConnectionInternal _withActiveConnectionAndDelegate:] ()
#4  0x30b97106 in ___ZN27URLConnectionClient_Classic26_delegate_didFinishLoadingEU13block_pointerFvvE_block_invoke ()
#5  0x30b95d16 in ___ZN27URLConnectionClient_Classic18_withDelegateAsyncEPKcU13block_pointerFvP16_CFURLConnectionPK33CFURLConnectionClientCurrent_VMaxE_block_invoke_2 ()
#6  0x30e64980 in CFArrayApplyFunction ()
#7  0x30b2d7fa in RunloopBlockContext::perform() ()
#8  0x30b2d6b8 in MultiplexerSource::perform() ()
#9  0x30b2d54c in MultiplexerSource::_perform(void*) ()
#10 0x30efc25a in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ ()
#11 0x30efb72a in __CFRunLoopDoSources0 ()
#12 0x30ef9f1e in __CFRunLoopRun ()
#13 0x30e64f4e in CFRunLoopRunSpecific ()
#14 0x30e64d32 in CFRunLoopRunInMode ()
#15 0x35d69662 in GSEventRunModal ()
#16 0x337b016c in UIApplicationMain ()
#17 0x00263fc8 in main at /Users/mepla/Projects/BApp-ios/BApp/main.m:15

我还添加了连接的初始化,以防出现问题:

NSMutableURLRequest *request= [[NSMutableURLRequest alloc] init];
    request.URL = requestURL;

    request.HTTPMethod = @"POST";

    NSUInteger timeinterval = [[NSDate date] timeIntervalSince1970];
    NSString *boundary = [NSString stringWithFormat:@"--%d", timeinterval];
    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
    [request addValue:contentType forHTTPHeaderField: @"Content-Type"];

    NSMutableData *postbody = [NSMutableData data];
    [postbody appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [postbody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"uuid\"\r\n\r\n%@", uuid] dataUsingEncoding:NSUTF8StringEncoding]];

    [postbody appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [postbody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"username\"\r\n\r\n%@", username] dataUsingEncoding:NSUTF8StringEncoding]];

    [postbody appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [postbody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"host\"\r\n\r\n%@", XMPPDomain] dataUsingEncoding:NSUTF8StringEncoding]];

    [postbody appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [postbody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"filename\"; filename=\"%@\"\r\n", _mediaIdentifier] dataUsingEncoding:NSUTF8StringEncoding]];
    [postbody appendData:[content dataUsingEncoding:NSUTF8StringEncoding]];
    [postbody appendData:[NSData dataWithData:_uploadData]];
    [postbody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];

    [request setHTTPBody:postbody];
    [request setTimeoutInterval:NSURLConnectionTimeout];


    _rawResponseData = [NSMutableData data];
    _connection = [[NSURLConnection alloc]
                   initWithRequest:request
                   delegate:self startImmediately:NO];

    [_connection scheduleInRunLoop:[NSRunLoop mainRunLoop]
                           forMode:NSDefaultRunLoopMode];

    [_connection start];

所以,对此问题的任何帮助都非常感谢。请记住,这段代码在很长一段时间内都运行正常,而且我无处可去。 :(

提前谢谢。

1 个答案:

答案 0 :(得分:0)

仔细观察这些线后:

[postbody appendData:[[NSString stringWithFormat:
    @"Content-Disposition: form-data; name=\"filename\"; filename=\"%@\"\r\n",
    _mediaIdentifier] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[content dataUsingEncoding:NSUTF8StringEncoding]];

不应该

[postbody appendData:[[NSString stringWithFormat:
    @"Content-Disposition: form-data; name=\"filename\"; filename=\"%@\"\r\n\r\n",
    _mediaIdentifier] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[content dataUsingEncoding:NSUTF8StringEncoding]];

注意:您可以使用diff工具使其显而易见;)

但是,正如我的评论中已经建议的那样,我会添加一个Content-Type标题:

[postbody appendData:[[NSString stringWithFormat:
    @"Content-Disposition: form-data; name=\"filename\"; filename=\"%@\"\r\n",
    _mediaIdentifier] dataUsingEncoding:NSUTF8StringEncoding]];    
[postbody appendData:[@"Content-Type: XXX/xxx\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[content dataUsingEncoding:NSUTF8StringEncoding]];