2

我对这个问题提出了我的问题Display photolibrary images in an effectual way iPhoneHighly efficient UITableView "cellForRowIndexPath" method to bind the PhotoLibrary imagesNSBlockOperation或NSOperation with ALAsset Block使用ALAsset显示照片库图像URL

所以我想请求的答案不重复这一个没有阅读下面的细节:)

让我们来到这个问题,

我研究一下我上面提到的问题的详细和我找到了关于操作队列来自here的文档。

所以我创建了一个示例应用程序,通过ALAsset块使用操作队列显示七个照片库图像。

以下是示例应用程序的详细信息。

步骤1:

在NSOperationalQueueViewController viewDidLoad中方法,我已经检索到的所有光画廊ALAsset URLs在名为urlArray阵列。

步骤2:

在所有的URL被添加到urlArray,所述如果(组=零!)条件将在assetGroupEnumerator假,所以我已经创建了一个NSOperationQueue,然后创建7分的UIImageView的通过for循环,创造了我的NSOperation子类对象与相应的图像的视图URL为每一个和添加他们到NSOperationQueue

请参阅我的NSOperation子类here

请参阅我的实施(VierwController)类here

让我们来谈谈这个问题。

它不一致地显示所有七个图像。一些图像丢失。缺少的顺序是多次更改(一次不显示第六和第七次,而另一次不显示第二次和第三次)。控制台日志显示找不到照片图片号码。但是,URL会被正确记录。

你可以看到日志的详细信息here

我的课上有错误吗?

此外,当我通过上述operational queue文档时,我已阅读约NSBlockOperation。在处理ALAsset块时,是否需要执行NSBlockOperation而不是NSOperation

NSBlockOperation介绍说

使用原样执行一个或多个块对象, 并发的类。因为它可以执行多个块,操作对象块使用组语义进行操作;只有当所有关联块都完成执行时,才会考虑完成操作本身 。

如何在ALAsset块中实现NSBlockOperation关于我的示例应用程序?

我已经通过堆栈溢出问题Learning NSBlockOperation。但是,我没有想到用ALAsset块实现NSBlockOperation

回答

4

您的DisplayImages NSOperation子类中有一行用于更新UI(DisplayImages。M线54):

self.imageView.image = topicImage; 

此操作队列在后台线程上运行,而我们知道,你应该只在主线程中更新UI的状态。由于更新的图像视图的视图绝对更新UI,这可以简单地固定通过用包裹呼叫:

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

这使异步调用在主队列来更新与所述图像的UIImageView的。它是异步的,因此您的其他任务可以在后台进行调度,并且它在主队列(主线程)上运行时很安全。

+0

太棒了......“我看到他之前在线,”你应该只更新主线程上UI的状态“。现在我很好理解它的含义:) ..谢谢abizern。你是rockzzzz ... – 2012-07-24 07:00:44

5

这是关于“如何使用ALAsset库访问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。 使用imageThumbnailArrayUIScrollView上显示,您的滚动速度不会很慢....并使用imageOriginalArray来放大图像预览。

'loadScrollView:' 方法,这是UIScrollView如何相似图片iPhoneSimulator

#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]; 
} 

在这里,你可以找到像button已经被点击了哪个 -

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

希望本教程将帮助您和许多搜索相同的用户。谢谢!

+0

感谢您的快速回复。我需要使用他们的ALAsset网址显示照片库图像。让我们考虑在启动应用程序之前,我已经在我的数据库中包含了所有的照片库图片网址。对于上述(我的答案)的目的,我可以通过“UIImagePickerController”显示照片库图像,而无需使用ALSAsset。对?所以请张贴答案“显示照片库图像使用他们的ALAsset网址,我想你可以回答。 – 2012-07-23 07:26:57

+0

正在使用UIImagePickerController ????,.... nslog”assetsArray“..你会看到它包含所有图片的网址... – TheTiger 2012-07-23 07:29:15

+0

对不起,如果我错了:)。让我澄清一件事情。我认为assetsArray数组包含ALAsset对象,而不是一个NSUrl或资源的网址,对吗? – 2012-07-23 07:33:26