0

온라인으로 다운로드되는 각 셀의 이미지를 보여주는 uitableview가 있습니다.NSBlock 조작이 취소되지 않습니다.

이 호출을 비동기로 만들려면 NSBlockoperation을 사용합니다. 이전에 GCD를 사용했기 때문에 이것을 사용하는 것을 선호하지만 GCD를 취소 할 수는 없습니다. 그 이유는 내가 뷰를 떠날 경우 이미지가 앱의 백그라운드에서 다운로드되고 이전 뷰를 다시 볼 때 GCD가 큐를 다시 큐에 넣을 것이기 때문에 결과적으로 전체 이미지 스택과 사용자는 uitableview를 보지 못합니다. 그래서 NSBlockoperation을 선택합니다.

그러나 내 블록이 취소되지 않습니다. 이것은 내가 사용하는 코드입니다 (그것은의 일부입니다 - (무효)있는 tableView :있는 tableView didSelectRowAtIndexPath (jQuery과 *) : (NSIndexPath *) indexPath는 {) :

// Create an operation without any work to do 
    downloadImageOperation = [NSBlockOperation new]; 

    // Make a weak reference to the operation. This is used to check if the operation 
    // has been cancelled from within the block 
    __weak NSBlockOperation* operation = downloadImageOperation; 


    // Give the operation some work to do 
    [downloadImageOperation addExecutionBlock: ^() { 
     // Download the image 
     NSData *data = [NSData dataWithContentsOfURL:[newsimages objectAtIndex:indexPath.row]];; 
     UIImage *image = [[UIImage alloc] initWithData:data]; 
     NSLog(@"%@",image); 
     // Make sure the operation was not cancelled whilst the download was in progress 
     if (operation.isCancelled) { 
      return; 
      NSLog(@"gestopt"); 
     } 
     if (image != nil) { 

      NSData* imageData = UIImagePNGRepresentation(image); 

      [fileManager createFileAtPath:path contents:imageData attributes:nil]; 
      cell.imageView.image = image; 
      cell.imageView.layer.masksToBounds = YES; 
      cell.imageView.layer.cornerRadius = 15.0; 

     } 

     // Do something with the image 
    }]; 

    // Schedule the download by adding the download operation to the queue 
    [queuee addOperation:downloadImageOperation]; 

I 취소이 코드를 사용했습니다는 :

-(void)viewDidDisappear:(BOOL)animated { 
[downloadImageOperation cancel]; 
} 

그러나 NSLog는 내보기가 사라진 후에도 (거기에 nslog를 두었습니다.) 여전히 블록이 있음을 알립니다.

2012-09-12 21:32:31.869 App[1631:1a07] <UIImage: 0x3965b0> 
2012-09-12 21:32:32.508 App[1631:1907] <UIImage: 0x180d40> 
2012-09-12 21:32:32.620 App[1631:707] view dissappear! 
2012-09-12 21:32:33.089 App[1631:3a03] <UIImage: 0x3a4380> 
2012-09-12 21:32:33.329 App[1631:5a03] <UIImage: 0x198720> 

주의 사항 :

답변

1

당신의 코드가 더이 결코 나타납니다 ..이보기에 표시되는 4 셀 때마다, 그래서 나는 그들이 큐에 여전히보기를 떠나더라도 생각 한 블록 이상 대기 중 -이게 맞습니까? 그렇지 않다면 작업 취소가 아닌 대기열에 '취소'를 보내야합니다.

어쨌든, 문제는 대부분이 라인 :

다운로드가 동 기적으로 당신을 위해 수행되고 있음을
NSData *data = [NSData dataWithContentsOfURL:[newsimages objectAtIndex:indexPath.row]];; 

- 그래서 당신이 보내는 경우가 볼 수 없습니다 취소 만이 메시지 후 '취소' 오랜 시간. 이것이 대부분의 개발자가 비동기 NSURLConnections를 사용하여 동시 NSOperations를 사용하여 다운로드를하는 이유입니다. 따라서 취소 메시지를 실시간으로 가져옵니다.

이것을 ARC라고 가정하면 dealloc에 ​​로그를 추가하여 실제로 작업이 완료되었거나 취소되었고 제대로 릴리스되었는지 확인할 수 있습니다. [위의 기록은 반환 이후이므로 절대로 호출되지 않습니다. 당신은 취소 된 메시지를 주변에 더 많이 뿌려서 취소 할 수있게 되 자마자 멈추게해야합니다.]

+0

실제로 모든 uitableviewcell에 대해 nsblockoperation이 만들어지고 실행 블록이 추가됩니다. 이 코드는 다른 질문지에서 stackoverflow에있는 누군가에 의해 제공되었지만, 이제는 무엇을 사용해야하는지 혼란 스럽습니다. 필자는 많은 튜토리얼과 예제를 보았 기 때문에 gcd를 시도했기 때문에 블록을 취소 할 수 없다는 것을 알았으므로 nsblockoperation을 사용하여 familliar가 아닌 곳을 알 수 없었습니다. (ive는 문서와 예제를 읽었지만) – Prastow

+0

You 블록 정렬을 '정렬'할 수 있습니다. '__block BOOL cancel'아이 바르가 있습니다. 각 블록은 중요한 작업을 시작하기 전에이를 검사합니다. 취소하려는 경우 플래그를 설정 한 다음 블록 완료를 기다립니다 (dispatch_group을 사용하는 경우이 작업을 수행 할 수 있음). 나는 이것을 항상 사용합니다. 블록은 몇 밀리 초 안에 완료됩니다. 실제로 NSOperations와 함께 사용하는 것과 동일한 기술입니다. 이 작업을 수행하는 방법을 알고 싶다면 동시 작업과 비동기 NSURLConnections를 사용하는 github에서 간단하고 쉽게 채택 할 수있는 프로젝트를 추가하십시오. https://github.com/dhoerl/NSOperation-WebFetches-MadeEasy –

+0

링크를 제공했지만 __block BOOL cancel ivar을 찾을 수 없습니다. 또한 블록에 관한 다른 주제를 읽으면서 NO로 설정 한 BOOL을 사용하여 취소 할 수 있으므로 다른 블록은 대기열에 저장되지 않습니다. 나는 내 코드처럼 생각한다. (operation.isCancelled) {맞습니까? 그러나 이미 대기열에 있고 사용자가 화면을 떠난다면 어떻게 될까요?(viewdiddissappear) 대기열을 비우는 방법 (현재 내가 제거 할 수 없다는 것을 알고 있습니다.) – Prastow