Iphone 加载200+;UIScrollView中的子视图图像

Iphone 加载200+;UIScrollView中的子视图图像,iphone,objective-c,ios,Iphone,Objective C,Ios,我正在使用ALAssetLibrary开发一个类似的程序,比如iPhone中的照片。我正在尝试在滚动视图中加载图像。当相册有少量图片时,一切正常。但是当我尝试加载包含200多张照片的相册时,我的程序结束时没有任何错误消息。有人知道这个节目吗? 以下是我加载滚动视图的代码: - (void)loadScrollView { for (UIView *v in [scrollview subviews]) { [v removeFromSuperview]; } CGRect scroll

我正在使用ALAssetLibrary开发一个类似的程序,比如iPhone中的照片。我正在尝试在滚动视图中加载图像。当相册有少量图片时,一切正常。但是当我尝试加载包含200多张照片的相册时,我的程序结束时没有任何错误消息。有人知道这个节目吗? 以下是我加载滚动视图的代码:

- (void)loadScrollView
{
for (UIView *v in [scrollview subviews]) {
    [v removeFromSuperview];
}

CGRect scrollFrame = [self frameForPagingScrollView];
scrollview = [[UIScrollView alloc] initWithFrame:scrollFrame];

CGRect workingFrame = scrollview.frame;
workingFrame.origin.y = 0;

photoCount = [info count];
for(NSDictionary *dict in info) {
    UIImageView *imageview = [[UIImageView alloc] initWithImage:[dict objectForKey:UIImagePickerControllerOriginalImage]];
    [imageview setContentMode:UIViewContentModeScaleAspectFit];
    imageview.frame = workingFrame;

    [scrollview addSubview:imageview];
    [imageview release];
    [scrollview setPagingEnabled:YES];
    [scrollview setDelegate:self];
    [scrollview setAutoresizesSubviews:YES];
    [scrollview setAutoresizingMask:UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight];
    [scrollview setShowsVerticalScrollIndicator:NO];
    [scrollview setShowsHorizontalScrollIndicator:NO];

    workingFrame.origin.x = workingFrame.origin.x + workingFrame.size.width;

}

[self setScrollViewContentSize];
[[self view] addSubview:scrollview];
}

提前谢谢大家

您应该使用滚动视图委派来确定当前屏幕上将显示哪些图像,并且只将这些图像加载到内存中


此外,如果显示的图像比实际图像尺寸小得多,则应调整图像大小并使用较小的图像。

我个人将所有
UIImageView
对象放在我的
UIScrollView
上,但仅为当前可见的对象设置图像属性(并为那些不再可见的对象清除图像属性)。如果您有数千个图像,即使这样也可能太浪费(可能您甚至不想保留
UIImageView
对象,即使没有它们的
image
属性集,也是如此),但如果您要处理数百个对象,我发现这是一个很好的简单解决方案,解决了
UIImage
对象消耗内存的关键问题:

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.scrollView.delegate = self;

    // all of my other viewDidLoad stuff...
}

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

    [self loadVisibleImages];
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    [self loadVisibleImages];
}

- (void)loadVisibleImages
{
    CGPoint contentOffset = self.scrollView.contentOffset;
    CGRect  contentFrame  = self.scrollView.bounds;
    contentFrame.origin = contentOffset;

    for (UIImageView *imageView in _imageViews) // _imageViews is (obviously) my array of images 
    {
        if (CGRectIntersectsRect(contentFrame, imageView.frame))
        {
            imageView.image = ... // set the image property
        }
        else
        {
            imageView.image = nil;
        }
    }
}
这是一些代码的一个片段,这些代码正在做一些其他的事情,因此您的实现显然会有很大的不同,但它展示了如何使用
scrollViewDidScroll
来确定哪些图像是可见的,并适当地加载/卸载图像。如果您还想删除/添加
UIImage,您可能需要进一步修改查看
对象,但显然必须更改“此imageview是否可见”的逻辑,而不是利用所有
UIImageView
对象的


我不确定我是否正确阅读了您的代码,但是您是否也将所有的
UIImage
对象放在字典中?这本身就是对内存的浪费。我通常将实际图像保存在某个持久存储中(例如,我使用
文档
文件夹,尽管您可以使用
核心数据
SQLite
,尽管后两者对大型图像的性能有很大影响)。我在内存中保存的唯一图像是UI活动使用的图像,出于性能原因,我将使用
NSCache
对象保留一些图像,但我会从持久存储而不是活动内存中提取它们。

为什么不使用
UICollectionView
UICollectionViewController
类onViewController参考

示例代码

您的图像最终将成为
UICollectionViewCell
的实例。数据源和委托协议方法与UITableView方法类似。即,它们提供了一种机制,
UICollectionViewController
将重用
UICollectionViewCell

使用这些类的好处是,它们的使用方式与
UITableViewControllers
类似,它们可以帮助您解决内存压力问题


祝你好运!

控制台中看不到内存警告?(级别1和/或2)一次分配200 UIImageView可能不是一个好主意(我不相信用户可以在同一屏幕上看到所有警告,对吗?),一个更好的方法是使用某种重用机制。非常感谢您的回答,我想我现在理解了这个问题…并且很快将修改代码…我非常感谢您的建议…是的,所有对象都在dict中,因为图片数据不是静态的,当用户从他的相机拍照时,任何时候都可以,new照片会在那里…你认为将它们保存在持久存储中是一个好方法吗?但我认为如果本地相册中有任何更改,程序需要读取和修改文件。@user1156202实际上,
ALAssetLibrary
本身就是一个完美的持久存储。无需求助于其他任何东西。只需抓取
ALAsset 对象(漂亮且小),对于那些可见的对象,您可以抓取
缩略图
属性并使用该属性以获得非常快的响应时间。在我的设备上,有500多张图像,我甚至可以使用
defaultRepresentation.fullScreenImage
(对于缩略图图像库,我不建议这样做,但我只是在测试LoadVisibleMages逻辑)以确保正确加载可见图像和卸载屏幕外图像。效果很好。