NSURLConnection和NSURLConnectionDataDelegate:不会触发连接回调

时间:2016-04-10 11:09:18

标签: ios objective-c nsurlconnectiondelegate

我想从我的服务器进行文件下载。 我的代码我使用的是由

委派的自定义类
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://example.com"]];
            if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.0")) {
                DownloadCallback *dc = [[DownloadCallback alloc] initWithCallbackProgress:^(long long res){
                    NSLog(@"%lld", res);
                } withCallbackReady:^(long long res){
                    NSLog(@"READY %lld", res);
                    [[NSOperationQueue mainQueue] addOperationWithBlock:^{

                    }];

                } withCallbackError:^(NSError * error) {
                    NSLog(@"READY %@", error.domain);
                }];

                NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:dc];
//                [connection setDelegateQueue:[[NSOperationQueue alloc] init]];
                [connection start];

头:

@interface DownloadCallback: NSObject<NSURLConnectionDataDelegate>{
     @private void (^_progressHandler)(long long someParameter);
     @private void (^_readyHandler)(long long someParameter);
     @private void (^_errorHandler)(NSError *someParameter);
}
-(id) initWithCallbackProgress:(void(^)(long long))handler withCallbackReady:(void(^)(long long))handlerReady  withCallbackError:(void(^)(NSError*))handlerError;
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
@end

体:

@implementation DownloadCallback
-(id) initWithCallbackProgress:(void(^)(long long))handler withCallbackReady:(void(^)(long long))handlerReady  withCallbackError:(void(^)(NSError*))handlerError{
    self = [super init];
    if (self) {
        _progressHandler = [handler copy];
        _readyHandler = [handlerReady copy];
        _errorHandler = [handlerError copy];
    }
    return self;
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
   // self.expectedTotalSize = response.expectedContentLength;

    // Call completion handler.
    if (_readyHandler != nil)
        _readyHandler(response.expectedContentLength);

    // Clean up.
//    [_completionHandler release];
    _readyHandler = nil;
    _progressHandler = nil;
    _errorHandler = nil;
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
//    self.recievedData += data.length;
    if (_progressHandler != nil)
        _progressHandler(data.length);
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    if (_errorHandler != nil)
        _errorHandler(error);
}
@end

但是回调事件没有被解雇!一点都没有!

简单的同步代码完美地工作:

    // Send a synchronous request
    NSURLRequest * urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com"]];
    NSURLResponse * response = nil;
    NSError * error = nil;
    NSData * data = [NSURLConnection sendSynchronousRequest:urlRequest
                                          returningResponse:&response
                                                      error:&error];
    if (error == nil) {
        // Parse data here
    }

但我需要回调!怎么解决?我在stackoverflow中找不到解决方案。 此外,如果我使用一个简单的委托代替主要类而不是DownloadCallback:连接回调也不会被触发。

1 个答案:

答案 0 :(得分:0)

将dealloc方法添加到回调类中,并在其中输出断点或日志语句。在调用回调之前查看它是否已被释放。

如果是这种情况,您的回调类实例将很快被销毁。使它成为一个类的属性,肯定会比请求更长寿。

此外,您应该确保此代码:

NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:dc];
[connection start];
在一个线程上调用

比连接更长,并且有一个runloop。实现此目的的最简单方法是在主队列上调用该代码。您的代码示例未显示调用的队列。如果它不起作用,我认为这是因为你在后台队列上调用它。 您可以从您想要/需要的委托回调中调度到后台队列。

作为旁注,如果要构建新内容,则应尝试使用NSURLSession而不是NSURLConnection。 NSURLSession更安全,更易于使用且不被弃用。 NSURLConnection已弃用。