【问题标题】:iOS - Create a Photo Viewer like Photo appiOS - 创建像照片应用一样的照片查看器
【发布时间】:2011-12-20 15:10:38
【问题描述】:

我正在尝试在 iOS 中创建一个类似 Apple Photos 应用程序的照片查看器。 布局没问题,但它收到内存警告然后崩溃。为什么?即使我从应用程序文档文件夹中加载 7/8 图像也会发生这种情况。我必须用特定系统管理内存吗?我在 iOS 5 中使用 ARC。

编辑:

代码:

for (int i=0; i<[dataSource count]; i++) {
        UIButton *button=[UIButton buttonWithType:UIButtonTypeCustom];
        [button setImage:[dataSource objectAtIndex:i] forState:UIControlStateNormal];
        [[button titleLabel] setText:[NSString stringWithFormat:@"%i",i+1]];
        [button addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
        [[button layer] setBorderWidth:1];
        [[button layer] setBorderColor:[UIColor darkGrayColor].CGColor];
        if (i==0) {
            [button setFrame:CGRectMake(x, y, width, height)];
        } else {
            if (i%5==0) {
                nRow++;
                x=18;
                [button setFrame:CGRectMake(x, (y*nRow), width, height)];
            } else {
                [button setFrame:CGRectMake(x+space+width, (y*nRow), width, height)];
                x=button.frame.origin.x;
            }
        }
        [[self view] addSubview:button];
    }

这段代码的主要部分是前 6 行,之后是所有的 x 和 y。 dataSource 是一个声明为属性(非原子,强)的 NSArray。它包含 UIImage 对象。

【问题讨论】:

  • @user523234 简单接收内存警告然后崩溃

标签: ios memory photo automatic-ref-counting


【解决方案1】:

您应该懒惰地加载您的图片,同时重复使用您的按钮,以解决大量图片的可能性。

实施:

  1. 将图像文件的路径保留在数据数组中,而不是 UIImage 对象中。在需要时使用 imageWithContentsOfFile: 从路径中获取图像。
  2. 将第一个 z 按钮加载到滚动视图中,其中 z 是屏幕上一次出现的数字加上一行的值。
  3. 将我们当前所在的 UIViewController 设置为滚动视图的委托,并通过重新定位按钮和设置适当的图像和目标来响应偏移量的变化。

此外,如果 7/8 图像使您的应用程序崩溃,听起来您正在处理一些非常大的图像文件。尝试在文档目录中提供缩略图大小的版本(无论您的按钮大小是多少),或者如果图像是动态的,请参阅this post 以获取操作方法。

【讨论】:

    【解决方案2】:

    如果您可能正在使用 ImageNamed,这篇文章对我有很大帮助:

    http://www.alexcurylo.com/blog/2009/01/13/imagenamed-is-evil/

    主要

    请勿将 [UIImage imageNamed] 用于任何大量图像。这是邪恶的。它会降低你的应用程序和/或 Springboard,即使你的应用程序自己只使用一点点内存。

    最好自己实现缓存

    这是建议的缓存图像示例:

    - (UIImage*)thumbnailImage:(NSString*)fileName
    {
       UIImage *thumbnail = [thumbnailCache objectForKey:fileName];
    
       if (nil == thumbnail)
       {
          NSString *thumbnailFile = [NSString stringWithFormat:@"%@/thumbnails/%@.jpg", [[NSBundle mainBundle] resourcePath], fileName];
          thumbnail = [UIImage imageWithContentsOfFile:thumbnailFile];
          [thumbnailCache setObject:thumbnail forKey:fileName];
       }
       return thumbnail;
    }
    

    【讨论】:

    • @BartłomiejSemańczyk 感谢您的提示,我已经更新了我的答案
    猜你喜欢
    • 2018-03-25
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 2011-09-12
    • 2012-07-06
    • 2013-06-02
    • 2013-02-17
    • 1970-01-01
    相关资源
    最近更新 更多