【问题标题】:NSURLConnection data received after connectionDidFinishLoadingconnectionDidFinishLoading 后收到的 NSURLConnection 数据
【发布时间】:2013-02-21 10:47:15
【问题描述】:

我有一个关于 NSURLConnection 的问题: 我想下载一张图片:

NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];

第一个(正确)调用的委托是

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

在这被调用一次之后:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

马上:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection

到这里为止一切都是正确的,但是在再次触发 connectionDidFinishLoading 后,同一连接的 didReceiveData 委托,我通过以下方式识别连接:

NSString * connectionKey = [[[connection originalRequest] URL] absoluteString];

这可能吗?

更新,更多信息:

我的应用程序触发了许多同时连接,并且我将任何连接的信息存储在字典中,当调用委托时,我使用密钥检索连接信息:NSString * connectionKey = [[[connection originalRequest] URL] absoluteString];对于 99% 的连接,一切都很好,但对于一个(每次都一样!)连接我有这种行为


这里是完整的实现:

    - (void)downloadFileFromUrl:(NSURL *)url
                     inPath:(NSString *)completeFilePath
          dataReceivedBlock:(void (^)(long long byteDownloaded ,long long totalByte))dataReceivedBlock
                   endBlock:(void (^)(NSString * downloadPath, NSDictionary * responseHeaders))endBlock
                  failBlock:(void (^)(NSString * downloadPath, NSDictionary * responseHeaders, NSError * error))failBlock
{
    //save the connection infos       
NSMutableDictionary * requestData = [[NSMutableDictionary alloc] init];
if(dataReceivedBlock)
[requestData setObject:[dataReceivedBlock copy] forKey:@"dataReceivedBlock"];
if(endBlock)
[requestData setObject:[endBlock copy] forKey:@"endBlock"];
if(failBlock)
[requestData setObject:[failBlock copy] forKey:@"failBlock"];

        [requestData setObject:[NSNumber numberWithBool:YES] forKey:@"usingBlock"];
        [requestData setObject: completeFilePath forKey:@"downloadDestinationPath"];

    //delete the file if already on fs
    if([[NSFileManager defaultManager] fileExistsAtPath: completeFilePath])
        [[NSFileManager defaultManager] removeItemAtPath:completeFilePath error:nil];

    // Create the request.
    NSURLRequest * urlRequest = [NSURLRequest requestWithURL:url cachePolicy:NSURLCacheStorageAllowed timeoutInterval:TIME_OUT];
    NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];
    if (!theConnection)
    {
        // Inform the user that the connection failed.
        failBlock(completeFilePath,nil,[NSError errorWithDomain:@"Connection fail" code:0 userInfo:nil]);
    }

    //add connection infos to the requests dictionary
    NSString * connectionKey = [[[theConnection originalRequest] URL] absoluteString];
    [self.requests setObject:requestData forKey:connectionKey];
}

这里是一个委托示例:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection

{

NSString * connectionKey = [[[connection originalRequest] URL] absoluteString];
NSMutableDictionary * requestData = [self.requests objectForKey:connectionKey];
NSFileHandle *file = [requestData objectForKey:@"fileHandle"];
[file closeFile];

//se la richiesta usa o no block
BOOL usingBlock = [[requestData objectForKey:@"usingBlock"] boolValue];
if(usingBlock)
{
    __block void (^endBlock)(NSString * , NSDictionary *) = [requestData objectForKey:@"endBlock"];
    if(endBlock)
        endBlock([requestData objectForKey:@"downloadDestinationPath"],[requestData objectForKey:@"responseHeaders"]);
}
else
    [self.delegate downloadEnded:[requestData objectForKey:@"responseHeaders"]];


//elimino dati richiesta
[self.requests removeObjectForKey:[NSString stringWithFormat:@"%@",connectionKey]];

//Inibisco standby
[UIApplication sharedApplication].idleTimerDisabled = NO;
}

【问题讨论】:

  • 这是什么意思??你是说在你的 connectionDidFinishLoading: 方法之后调用了 didReceiveData 方法??
  • 是的!我的应用程序触发了许多同时连接,并且我将任何连接的信息存储在字典中,当调用委托时,我使用密钥检索连接信息: NSString * connectionKey = [[[connection originalRequest] URL] absoluteString];对于 99% 的连接,一切都很好,但对于一个(每次都一样!)连接我有这种行为
  • 向你的代码展示你是如何创建连接并初始化它的。有一件事要清楚。它不会像你所说的那样在任何情况下调用。这将是一个问题其他地方..您可以在任何地方手动调用它。发布 NSUrlConnection 委托和初始化方法的整个代码
  • 你在哪里初始化连接?
  • 我从来没有手动调用过任何委托,关键是:连接 didReceiveData:在 connectionDidFinishLoading 之后调用(当我从 self.requests 字典中删除连接信息时),然后在 didReceiveData:我无法检索正确的 NSMutableDictionary * requestData

标签: iphone ios objective-c nsurlconnection nsurlconnectiondelegate


【解决方案1】:

这是不可能的。一定是不同的连接回调。

确保每个连接使用唯一的委托,或同一委托中的唯一开关分支。

【讨论】:

  • @Kappe 您可以测试单个问题的连接 URL。基本上,当您收到委托方法 didfinishloading 时,连接就会关闭
【解决方案2】:

显然解决方案非常简单-_- 错误在连接密钥标识符中:

NSString * connectionKey = [[[connection originalRequest] URL] absoluteString];

我的假设是密钥是唯一的,但是如果我在同一个 url 为同一个文件进行 x 次并行下载,那么假设是错误的 ;)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-12
    • 1970-01-01
    相关资源
    最近更新 更多