2

내 질문에 대해 질문 사항입니다. Display photolibrary images in an effectual way iPhoneHighly efficient UITableView "cellForRowIndexPath" method to bind the PhotoLibrary images.ALAsset URL을 사용하여 사진 라이브러리 이미지를 표시하기 위해 NSBlockOperation 또는 NSAsperation with ALAsset URL

그래서, 내가 위에서 언급 한 문제에 대한 자세한 연구 한

, 아래의 세부 사항

의 문제에 오게

을 :) 읽지 않고 답이 하나에 중복되지 않도록 요청하고 싶습니다

및 나는 작업 큐에 관한 문서here에서 발견했습니다.

그래서 ALAsset 블록을 통해 작업 대기열을 사용하여 7 개의 사진 라이브러리 이미지를 표시하는 하나의 샘플 애플리케이션을 만들었습니다.

다음은 샘플 애플리케이션 세부 정보입니다.

단계 1 : NSOperationalQueueViewController 의 viewDidLoad 방법에

, I는 urlArray라는 배열의 모든 사진 갤러리 ALAsset URLs을 취득했다.

2 단계 : 모든 URL이 urlArray에 추가 한 후

경우 (그룹 = 0!) 조건이 assetGroupEnumerator에 허위, 그래서 나는 NSOperationQueue을 생성하고 생성 한 일곱 개 UIImageView에 for 루프를의와는 각각에 대해 해당 이미지보기로URL을 내 NSOperation 서브 클래스 객체를 생성 은에에게 그들을 추가 0.

NSOperation 하위 클래스 here을 참조하십시오.

구현 (VierwController) 클래스here을 참조하십시오.

문제를 해결하겠습니다.

7 개의 이미지가 모두 일관되게 표시되지 않습니다. 일부 이미지가 누락되었습니다. 누락 된 주문은 여러 번 변경됩니다 (한 번은 여섯 번째와 일곱 번째를 표시하지 않으며 한 번은 두 번째와 세 번째 만 표시하지 않음). 콘솔 로그에 사진 번호을 찾을 수 없습니다. 그러나 URL은 올바르게 기록됩니다.

로그 세부 사항 here을 볼 수 있습니다.

수업에 실수가 있습니까?

또한 위에서 언급 한 operational queue 설명서를 읽을 때 나는 NSBlockOperation에 대해 읽었습니다. ALAsset 블록을 처리하는 동안 NSOperation 대신 NSBlockOperation을 구현해야합니까?

NSBlockOperation 설명

하나 이상의 블록이 동시에 개체를 실행하기 위해 그대로 사용하는 클래스를 말한다. 둘 이상의 블록을 실행할 수 있으므로 블록 작업 객체는 그룹 의미를 사용하여 작동합니다. 연관된 블록이 모두 실행을 완료 한 경우에만 작업이 완료된 것으로 간주됩니다.

NSBlockOperation을 샘플 애플리케이션과 관련하여 ALAsset 블록과 함께 구현하려면 어떻게해야합니까?

스택 오버플로 관련 질문 Learning NSBlockOperation. 그러나, 나는 ALAsset 블록으로 NSBlockOperation을 구현할 생각이 전혀 없었습니다 !!

답변

4

UI를 업데이트하는 DisplayImages NSOperation 하위 클래스에 행이 있습니다 (DisplayImages.m 라인 54) :

self.imageView.image = topicImage; 

이 작업 큐는 백그라운드 스레드에서 실행되고, 우리는 당신이 단지 주 스레드에서 UI의 상태를 업데이트해야합니다 것을 알고있다. 이미지 뷰의 뷰를 갱신하는 것은 확실히 UI를 업데이트하기 때문에, 이것은 단순히 함께 통화를 배치함으로써 해결 될 수

dispatch_async(dispatch_get_main_queue(), ^{ 
    self.imageView.image = topicImage; 
}); 

이 이미지와의 UIImageView 업데이트 메인 큐에 비동기 호출을 둔다. 비동기식이므로 다른 작업을 백그라운드에서 예약 할 수 있으며 기본 스레드 인 메인 대기열에서 실행되는 것처럼 안전합니다.

+0

위대한 ... "나는 이전에"주 스레드에서 UI의 상태 만 업데이트해야합니다. " 이제 나는 그 의미를 잘 이해했다 :) .. 감사합니다. u rockzzzz ... –

5

"ALAsset Library를 사용하여 iPhonePhoto Library의 모든 이미지에 액세스하고 iPhoneSimulator와 같은 UIScrollView에 표시하는 방법"에 대한 자습서입니다. 먼저 프로젝트에 AssetsLibrary.framework을 추가하십시오.

viewController.h 파일에서 #import <AssetsLibrary/AssetsLibrary.h> 헤더 파일을 가져옵니다.

이것은 당신의 viewController.h 파일

#import <UIKit/UIKit.h> 
#import <AssetsLibrary/AssetsLibrary.h> 
#import "AppDelegate.h" 

@interface ViewController : UIViewController <UIScrollViewDelegate> 
{ 
    ALAssetsLibrary *assetsLibrary; 
    NSMutableArray *groups; 
    ALAssetsGroup *assetsGroup; 

    // I will show all images on `UIScrollView` 
    UIScrollView *myScrollView; 

    UIActivityIndicatorView *activityIndicator; 

    NSMutableArray *assetsArray; 
    // Will handle thumbnail of images 
    NSMutableArray *imageThumbnailArray; 
    // Will handle original images 
    NSMutableArray *imageOriginalArray; 

    UIButton *buttonImage; 
} 

-(void)displayImages; 
-(void)loadScrollView; 

@end 

입니다 그리고 이것은 당신의 viewController.m 파일 - viewWillAppear:

#import "ViewController.h" 
#import <QuartzCore/QuartzCore.h> 

@implementation ViewController 

- (void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 

    assetsArray = [[NSMutableArray alloc]init]; 
    imageThumbnailArray = [[NSMutableArray alloc]init]; 
    imageOriginalArray = [[NSMutableArray alloc]init]; 

    myScrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0.0, 0.0, 320.0, 416.0)]; 
    myScrollView.delegate = self; 
    myScrollView.contentSize = CGSizeMake(320.0, 416.0); 
    myScrollView.backgroundColor = [UIColor whiteColor]; 

    activityIndicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; 
    activityIndicator.center = myScrollView.center; 
    [myScrollView addSubview:activityIndicator]; 
    [self.view addSubview:myScrollView]; 

    [activityIndicator startAnimating]; 

} 

viewDidAppear:

-(void)viewDidAppear:(BOOL)animated 
{ 
if (!assetsLibrary) { 
     assetsLibrary = [[ALAssetsLibrary alloc] init]; 
    } 
    if (!groups) { 
    groups = [[NSMutableArray alloc] init]; 
    } 
else { 
    [groups removeAllObjects]; 
} 

ALAssetsLibraryGroupsEnumerationResultsBlock listGroupBlock = ^(ALAssetsGroup *group, BOOL *stop) { 
     //NSLog(@"group %@",group); 
     if (group) { 
      [groups addObject:group]; 
     //NSLog(@"groups %@",groups); 
    } else { 
     //Call display Images method here. 
     [self displayImages]; 
     } 
}; 
ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError *error) { 
    NSString *errorMessage = nil; 
     switch ([error code]) { 
     case ALAssetsLibraryAccessUserDeniedError: 
      case ALAssetsLibraryAccessGloballyDeniedError: 
      errorMessage = @"The user has declined access to it."; 
       break; 
      default: 
      errorMessage = @"Reason unknown."; 
      break; 
    } 
    }; 
    [assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:listGroupBlock failureBlock:failureBlock]; 

} 

그리고 이것은 displayImages:입니다 방법 몸

-(void)displayImages 
{ 
// NSLog(@"groups %d",[groups count]); 
    for (int i = 0 ; i< [groups count]; i++) { 
    assetsGroup = [groups objectAtIndex:i]; 
     if (!assetsArray) { 
     assetsArray = [[NSMutableArray alloc] init]; 
     } 
     else { 
     [assetsArray removeAllObjects]; 
    } 

    ALAssetsGroupEnumerationResultsBlock assetsEnumerationBlock = ^(ALAsset *result, NSUInteger index, BOOL *stop) { 

      if (result) { 
       [assetsArray addObject:result]; 
      } 
    }; 
     ALAssetsFilter *onlyPhotosFilter = [ALAssetsFilter allPhotos]; 
     [assetsGroup setAssetsFilter:onlyPhotosFilter]; 
     [assetsGroup enumerateAssetsUsingBlock:assetsEnumerationBlock]; 

    } 

    //Seprate the thumbnail and original images 
    for(int i=0;i<[assetsArray count]; i++) 
    { 
     ALAsset *asset = [assetsArray objectAtIndex:i]; 
     CGImageRef thumbnailImageRef = [asset thumbnail]; 
     UIImage *thumbnail = [UIImage imageWithCGImage:thumbnailImageRef]; 
     [imageThumbnailArray addObject:thumbnail]; 

     ALAssetRepresentation *representation = [asset defaultRepresentation]; 
     CGImageRef originalImage = [representation fullResolutionImage]; 
     UIImage *original = [UIImage imageWithCGImage:originalImage]; 
     [imageOriginalArray addObject:original]; 
    } 

    [self loadScrollView]; 
} 

이제 두 array 하나 imageThumbnailArray이며, 또 다른 imageOriginalArray입니다 있습니다. 을 사용하면 UIScrollView에 표시되며 스크롤 속도가 느려지지 않습니다. imageOriginalArray을 사용하면 확대 된 이미지 미리보기를 사용할 수 있습니다.

는 는

'loadScrollView' 방법은,이

#pragma mark - LoadImages on UIScrollView 
-(void)loadScrollView 
{ 
    float horizontal = 8.0; 
    float vertical = 8.0; 

    for(int i=0; i<[imageThumbnailArray count]; i++) 
    { 
     if((i%4) == 0 && i!=0) 
     { 
      horizontal = 8.0; 
      vertical = vertical + 70.0 + 8.0; 
     } 

     buttonImage = [UIButton buttonWithType:UIButtonTypeCustom]; 
     [buttonImage setFrame:CGRectMake(horizontal, vertical, 70.0, 70.0)]; 
     [buttonImage setTag:i]; 
    [ buttonImage setImage:[imageThumbnailArray objectAtIndex:i] forState:UIControlStateNormal]; 
     [buttonImage addTarget:self action:@selector(buttonImagePressed:) forControlEvents:UIControlEventTouchUpInside]; 
     [myScrollView addSubview:buttonImage]; 
     horizontal = horizontal + 70.0 + 8.0; 

    } 

    [myScrollView setContentSize:CGSizeMake(320.0, vertical + 78.0)]; 
    [activityIndicator stopAnimating]; 
    [activityIndicator removeFromSuperview]; 
} 

iPhoneSimulator같은 UIScrollView에 어떻게 이미지입니다 그리고 여기 당신은 이미지 button 클릭 된 찾을 수 있습니다 -이 튜토리얼

#pragma mark - Button Pressed method 
-(void)buttonImagePressed:(id)sender 
{ 
    NSLog(@"you have pressed : %d button",[sender tag]); 
} 

희망을 당신과 같은 것을 찾는 많은 사용자를 도울 것입니다 .. 감사합니다!

+0

빠른 답장을 보내 주셔서 감사합니다. ALAsset URL을 사용하여 사진 라이브러리 이미지를 표시해야합니다. 앱을 실행하기 전에 데이터베이스에있는 모든 사진 라이브러리 이미지 URL을 가지고 있다고 생각합니다. 위의 (답변) 목적을 위해, 나는 "UIImagePickerController"를 통해 ALSAsset을 사용하지 않고 사진 라이브러리 이미지를 표시 할 수 있습니다. 권리? 그래서 제발 대답을 게시하십시오 "ALAsset URL을 사용하여 사진 라이브러리 이미지를 표시합니다. 당신이 대답 할 수있을 것 같아요. –

+0

UIImagePickerController 사용되는중인 ????, .... .... nslog 'assetsArray' .. 당신은 그것을 볼 수 있습니다 모든 이미지의 URL을 .... – TheTiger

+0

내가 잘못하면 죄송합니다 :) 한 가지를 명확히하자. assetsArray 배열에 ALAsset 객체가 포함되어 있습니다 (NSUrl 또는 Asset URL이 아님). –