我想从我的服务器进行文件下载。 我的代码我使用的是由
委派的自定义类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
:连接回调也不会被触发。
答案 0 :(得分:0)
将dealloc方法添加到回调类中,并在其中输出断点或日志语句。在调用回调之前查看它是否已被释放。
如果是这种情况,您的回调类实例将很快被销毁。使它成为一个类的属性,肯定会比请求更长寿。
此外,您应该确保此代码:
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:dc];
[connection start];
在一个线程上调用比连接更长,并且有一个runloop。实现此目的的最简单方法是在主队列上调用该代码。您的代码示例未显示调用的队列。如果它不起作用,我认为这是因为你在后台队列上调用它。 您可以从您想要/需要的委托回调中调度到后台队列。
作为旁注,如果要构建新内容,则应尝试使用NSURLSession而不是NSURLConnection。 NSURLSession更安全,更易于使用且不被弃用。 NSURLConnection已弃用。