2014-02-06 2 views
0

NSOperation 큐를 사용하여 이미지를 가져 와서 내 tableview 셀에 표시했습니다. 이미지가 다시 나타날 때까지로드 오버레이를 표시하고 작업이 완료되면 델리게이트를 암시 한 다음로드 오버레이를 제거합니다.NSOperationQueue에서 동기 서버 호출 시간 초과

이제 5 초 후에 가져 오기 작업을 시간 초과하고로드 오버레이를 제거하려고했지만 타이머 기반 접근 방식이 제대로 작동하지 않습니다. 제발 제안 해주세요.

#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 
+0

왜 타이머가 필요합니까? URL 요청에 타임 아웃을 설정 했으므로 요청 처리가 완료되면 'iData == nil'과 함께 5 초 후에 완료 핸들러를 호출해야합니다. –

+0

마틴, 그는 문제가 있습니다. NSMutableRequest.h comments에서 setTimeoutInterval에 대한 주석 "부하 작업의 인스턴스가 발생하면 (예 : 요청에 대해 바이트가 네트워크에서 수신 된 경우) 요청의 유휴 간격은 0으로 재설정됩니다." 그래서 간격을 5로 설정하지만 연결에 각각 4 초의 데이터가 걸리고 2 초가 지나면 연결이 시간 초과되지 않을 수도 있습니다. –

답변

0

당신은, 당신의 타이머를 작동하게하기 위해이 같은 것을 실행 루프가 필요합니다.

0

경우 왜이 내부

[self.delegate operationCompletedForURL:self.imageURL]; 

를 호출하지 않습니다 아래

내 코드?

if (iConnectionError) { 

마찬가지로, 해당 블록 내부에는 자체를 사용하면 안되기 때문에 __block 변수를 사용해야합니다. 나는 그것을 메인에 자신의 오토 릴리즈 풀을 설정하는 더 나은 것 같아요,

- (void)main 
{ 
    // your code 
    yourTimer = ... // create your timer 

    NSRunLoop* runLoop = [NSRunLoop currentRunLoop]; 
    [runLoop addTimer:yourTimer forMode:NSRunLoopCommonModes]; 
    [runLoop run]; 
} 

아, 그리고 :

+0

이 문장은 if 또는 else에 없기 때문에 어쨌든 호출됩니다. – Abhinav

+0

네 말이 맞아. 그런데 대표자가 타이머없이 올바르게 호출되고 있습니까? 가장 좋은 방법은 타이머를 사용하지 않고 요청 시간 제한을 사용하는 것입니다. –

+0

그래,하지만 요청의 타임 아웃은 실제로 그 기간에 요청을 타임 아웃하지 않았 음을 보증하지 않습니다. 서버 연결 설정에 시간이 걸리지 만 작동하지만 서버 연결이 이루어지면 서버가 응답 속도가 조금 느려지면 기본 시간 초과가 발생합니다. – Abhinav

관련 문제