【发布时间】:2014-02-06 16:15:10
【问题描述】:
我正在使用 NSOperation 队列来获取图像并将它们显示在我的 tableview 单元格上。在图像返回之前,我会显示加载叠加层,一旦操作完成,它就会提示委托,然后我删除加载叠加层。
现在,我想在 5 秒后让 fetch 操作超时并删除加载覆盖,但基于计时器的方法行不通。请提出建议。
下面是我的代码:
#import "MyImageFetchOperation.h"
#import "MyImageFetchController.h"
#import "MyHTTPRequest.h"
@interface MyImageFetchOperation ()
@property (nonatomic, strong) NSString *imageURL;
@property (nonatomic, weak) id <MyOperationCompletedDelegate> delegate;
@property (nonatomic, assign) BOOL isCompleted;
@property (nonatomic, weak) NSTimer *timeoutTimer;
@end
@implementation MyImageFetchOperation
@synthesize imageURL;
@synthesize delegate;
@synthesize isCompleted;
#define kMyImageFetchTimeout 5
#pragma mark -
#pragma mark Destruction
- (void)dealloc {
self.delegate = nil;
}
- (id)initWithImageURL:(NSString *)iImageURL delegate:(id)iDelegate {
if (self = [super init]) {
self.imageURL = iImageURL;
self.delegate = iDelegate;
}
return self;
}
- (void)main {
self.isCompleted = NO;
NSMutableURLRequest *aRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.imageURL]];
[aRequest setTimeoutInterval:kMyImageFetchTimeout];
[aRequest setHTTPMethod:@"GET"];
self.timeoutTimer = [NSTimer scheduledTimerWithTimeInterval:kMyImageFetchTimeout target:self selector:@selector(requestTimedOut) userInfo:nil repeats:NO];
[NSURLConnection sendAsynchronousRequest:aRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *iData, NSError *iConnectionError) {
if (!self.isCompleted) {
if (iConnectionError) {
[[MyImageFetchController sharedRunnerImageFetchControllerMy] urlFailed:self.imageURL];
}
UIImage *anImage = [UIImage imageWithData:iData];
if (anImage) {
[MyUtilities cacheFile:anImage withName:[self.imageURL runnerMD5HashMy] toDirectory:[self.delegate cacheDirectoryForImages]];
} else {
[[MyImageFetchController sharedRunnerImageFetchControllerMy] urlFailed:self.imageURL];
}
[self.delegate operationCompletedForURL:self.imageURL];
self.isCompleted = YES;
}
}];
}
- (void)requestTimedOut {
self.isCompleted = YES;
[self.timeoutTimer invalidate];
self.timeoutTimer = nil;
[[MyImageFetchController sharedRunnerImageFetchControllerMy] urlFailed:self.imageURL];
[self.delegate operationCompletedForURL:self.imageURL];
}
@end
【问题讨论】:
-
为什么需要计时器?您已对 URL 请求设置了超时,因此应在最迟 5 秒后调用完成处理程序,如果请求超时,则应使用
iData == nil。 -
马丁,他确实有问题。从 setTimeoutInterval 上的 NSMutableRequest.h cmets “因此,当发生负载活动的实例时(例如,从网络接收到请求的字节),请求的空闲间隔重置为 0”因此,如果他将间隔设置为5 但连接需要 4 个数据块,每个数据块需要 2 秒才能到达,连接甚至可能不会超时。
标签: ios objective-c cocoa-touch nsoperation nsoperationqueue