서버

2013-08-14 2 views
1

발을 NSData 로딩을 중지 I 기본적 배열로 이미지 데이터의 어레이를로드하기 방법을 가지고서버

예를 들어, 사용자가 멀리 이동하는 경우, I가 막을 수 있도록 할
-(void)loadImages:(NSMutableArray*)imagesURLS{ 
    //_indexOfLastImageLoaded = 0; 
    [_loadedImages removeAllObjects]; 
    _loadedImages = [[NSMutableArray alloc]init];; 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ 
     for (int i=0; i<imagesURLS.count;i++){ 
      NSLog(@"loading image for main image holder at index %i",i); 
      NSData *imgData = [NSData dataWithContentsOfURL:[imagesURLS objectAtIndex:i]]; 
      UIImage *img = [UIImage imageWithData:imgData]; 
      [_loadedImages addObject:img]; 
      //_indexOfLastImageLoaded++; 
     } 

     dispatch_async(dispatch_get_main_queue(), ^{ 
      NSLog(@"_loadedImages download COMPLETE");      
     }); 
    }); 

} 

보기 컨트롤러에서 이러한 이미지를로드 할 수 있습니다. 이렇게하는 가장 좋은 방법은 무엇입니까?

감사합니다.

답변

4

NSData dataWithContentsOfUrl:을 취소 할 수 없습니다. 취소 가능한 비동기 다운로드를 수행하는 가장 좋은 방법은 NSURLConnectionNSURLConnectionDataDelegate을 사용하는 것입니다.

청크로 들어오는 모든 데이터를 누적하도록 NSMutableData 객체를 설정합니다. 그런 다음 모든 데이터가 도착하면 이미지를 만들어 사용합니다. .H

@interface ImageDownloader : NSObject <NSURLConnectionDataDelegate> 
@property (strong, nonatomic) NSURLConnection *theConnection; 
@property (strong, nonatomic) NSMutableData *buffer; 
@end 

하는 .m

-(void)startDownload 
{ 
    NSURL *imageURL = [NSURL URLWithString: @"http://example.com/largeImage.jpg"]; 
    NSURLRequest *theRequest = [NSURLRequest requestWithURL: imageURL]; 
    _theConnection = [[NSURLConnection alloc] initWithRequest: theRequest delegate: self startImmediately: YES]; 
} 

-(void)cancelDownload 
{ 
    // CANCELS DOWNLOAD 
    // THROW AWAY DATA 
    [self.theConnection cancel]; 
    self.buffer = nil; 
} 

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
{ 
    // INITIALIZE THE DOWNLOAD BUFFER 
    _buffer = [NSMutableData data]; 
} 

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{ 
    // APPEND DATA TO BUFFER 
    [self.buffer appendData: data]; 
} 

-(void)connectionDidFinishLoading:(NSURLConnection *)connection 
{ 
    // DONE DOWNLOADING 
    // CREATE IMAGE WITH DATA 
    UIImage *theImage = [UIImage imageWithData: self.buffer]; 
} 
+0

이 기능을 사용하여 배열에서 이미지를로드하는 경우에도 모든 이미지를 다운로드하기 전에이 기능을 사용할 수 있습니까? 예를 들어 사용자가 인덱스 3의 이미지를로드하려고하고 데이터 배열 수가 3보다 크면 데이터에서 이미지를로드하고 그렇지 않으면 URL에서로드합니다. 설명에서이 클래스는 모든 데이터가 도착한 후에 만 ​​데이터에서 이미지를로드 할 수있게합니다. – royherma

+0

사진 하나당 하나의 NSURLConnection 객체를 사용하여 다운로드 할 수 있습니다. 이 클래스의 여러 인스턴스를 다운로드 관리자/컨트롤러에 보관할 수 있습니다. 이 기능을 NSOperation 하위 클래스에 포함시킬 수도 있습니다. [objc.io]에서 자세한 내용보기 (http://www.objc.io/issue-2/common-background-practices.html) – MJN

2

당신은 내가 당신 대신 행의 모든 ​​요청을 밀어 NSOperationQueue를 사용하도록 조언 취소 요청을 더 유연하게하려면

.

NSOperationQueue *queue = [[NSOperationQueue alloc] init]; 
    [queue setMaxConcurrentOperationCount:1]; 
    for (int i=0; i<allImagesCount; i++) { 
     [queue addOperationWithBlock:^{ 
      // load image 
     }]; 
    } 

    // for canceling operations 
    [queue cancelAllOperations]; 

당신이 현재 코드에서는 정적 필드를 정의 할 수 있으며 루프 체크하지만, 가장 좋은 방법은 SDWebImage 사용됩니다 - 로딩 이미지 비동기에 대한 https://github.com/rs/SDWebImage을.

+0

작업 수를 1로 설정하는 이유는 무엇입니까? 동시성 이점을 극적으로 감소시키지 않을까요? –

+0

그것은 단지 예일뿐입니다. 그것은 ipad 3와 같은 코어 및 장치의 장치에 달려 있습니다. ipad 2는 2로 설정해야하지만 ipad 2에서는 설정할 수 있습니다. 따라서 주 스레드의 상황에 따라 다릅니다. . – fenk

+0

NSData dataWithContentsOfUrl : 대기열 내에서의 작업으로 사용할 수 있습니까? – royherma