iPhone 3GS 上的 iOS 6.0 上的 UICollectionView 崩溃

Posted

技术标签:

【中文标题】iPhone 3GS 上的 iOS 6.0 上的 UICollectionView 崩溃【英文标题】:UICollectionView Crashes on iOS 6.0 on iPhone 3GS 【发布时间】:2013-01-11 12:18:41 【问题描述】:

应用程序在显示 UICollectionView 时可能会崩溃。它还会创建一个低内存崩溃日志。如何减少 UICollectionView 中的内存使用量?我在项目中使用 ARC。请帮助...(以下是我的代码)

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
    return [untaggedImagesArray count];


- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
    @autoreleasepool 

    static NSString *identifier = @"imageCell";
    imageCell *cvc = (imageCell *)[self.iamgesCollectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
    if(cvc == nil)
        NSArray *topLevelObjects = [[NSBundle mainBundle]loadNibNamed:@"imageCell" owner:nil options:nil];
        for(id currentObject in topLevelObjects)
            if([currentObject isKindOfClass: [imageCell class]])
                cvc = (imageCell*)currentObject;


                break;
            
        
    
    NSString *path = [untaggedImagesArray objectAtIndex:indexPath.row];
         NSString *path = [untaggedImagesArray objectAtIndex:indexPath.row];
    //[self performSelectorInBackground:@selector(getImage:) withObject:path];

    UIImage *cache_image = [images_cache objectForKey:path];

    if(cache_image)
    
        [cvc.imageView setImage:cache_image];
    
    else
    
        [self performSelectorInBackground:@selector(getImage:) withObject:path];
        //UIImage *img = [UIImage imageWithContentsOfFile:path];
        [images_cache setObject:cellImage forKey:path];
         [cvc.imageView setImage:cellImage];
    


    if([preTaggedPaths containsObject:path])
        [cvc.tagLabel setText:[tagStringsDict valueForKey:[NSString stringWithFormat:@"%d",indexPath.row]]];
        [cvc setUserInteractionEnabled:NO];
    else
        [cvc.tagLabel setText:@""];
        [cvc setUserInteractionEnabled:YES];
    

        if([selectedImagesPath containsObject:path])
            [cvc.checkImageView setImage:[UIImage imageNamed:@"checkbox_small_selected.png"]];
        else
            [cvc.checkImageView setImage:[UIImage imageNamed:@"checkbox_small_unselected.png"]];
        

//
    return cvc;
    




-(void)getImage:(NSString*)path
    cellImage = [UIImage imageWithContentsOfFile:path];


- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath

    NSLog(@"clicked to select at index%d",indexPath.row);
    imageCell *cvc = (imageCell*)[self.iamgesCollectionView cellForItemAtIndexPath:indexPath];
    NSString *pathString = [untaggedImagesArray objectAtIndex:indexPath.row];
    [cvc.checkImageView setImage:[UIImage imageNamed:@"checkbox_small_selected.png"]];
    [selectedImagesPath addObject:pathString];


- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath 
     NSLog(@"clicked to DEselect at index%d",indexPath.row);
    imageCell *cvc = (imageCell*)[self.iamgesCollectionView cellForItemAtIndexPath:indexPath];
    NSString *pathString = [untaggedImagesArray objectAtIndex:indexPath.row];
    [cvc.checkImageView setImage:[UIImage imageNamed:@"checkbox_small_unselected.png"]];
    [selectedImagesPath removeObject:pathString];
//    [cvc setSelected:NO];

-

(void)getImage:(NSString*)path
    //cellImage = [UIImage imageWithContentsOfFile:path];
    NSLog(@"image path: %@", path);
    cellImage = [UIImage imageNamed:path];


【问题讨论】:

尝试更改 getImage: 方法以使用“[UIImage imageWithContentsOfFile:path];”加载图像并告诉我它是否停止崩溃。 【参考方案1】:

您说崩溃是由于内存不足引起的!

一个可能的问题是你的图片加载机制(你的图片大小是多少?):

[UIImage imageWithContentsOfFile:path];

这将在您的集合视图中的每个单元格每次执行。

[UIImage imageNamed:@"name"];

例如缓存图片,而 imageWithContentsOfFile 不缓存!

所以 UIImage 的方法 imageNamed:imageWithContentsOfFile 做的事情略有不同。 imageNamed 将图像加载到一个特殊的系统缓存中,然后使用该图像路径的未来调用将返回缓存中的图像,而不是从磁盘重新加载它。 imageWithContentsOfFile 只是将图像加载到您指定的路径,但不进行缓存。对同一图像多次调用imageWithContentsOfFile 将导致内存中有多个副本。

如果这是您的问题,请尝试缓存图像或使用智能方式仅加载当前正在显示的图像。

【讨论】:

感谢@alex 的建议。我应该调整(创建缩略图)图像的大小。 有很多方法可以防止应用程序因内存过载而崩溃。就像我在回答中所说的那样,我会尝试仅加载真正显示在屏幕上的图像。进一步尝试为你自己缓存图像(例如 NSCache) 我已经应用了缓存,但在 8 张图像之后仍然无法正常工作。我已经通过图像缓存编辑了我的问题。 您是否尝试过使用仪器来跟踪您的内存使用情况并找到线索?你的图片尺寸是多少?如果您正在加载 50 张 1 MB 的图像,则应该清楚这不起作用...然后尝试仅加载您真正显示的图像

以上是关于iPhone 3GS 上的 iOS 6.0 上的 UICollectionView 崩溃的主要内容,如果未能解决你的问题,请参考以下文章

iPhone 3GS 上的 HTML5 WebSocket

调试 iPhone 3GS xcode 4.2.1

XE7 Update 1 选 iOS 8.1 SDK 发布 iPhone 3GS 实机测试

为啥我的弹出框在 iPhone 6 Plus 上的 iOS 8.1 中崩溃? iOS 8 工作(实际上是 Xcode 6.0 到 6.1 的错误)

Facebook Login 正在 Facebook Native 应用程序中打开,而不是在 ios 6.0 的 iphone 设备上的 Safari 浏览器中打开

iPhone 3GS + / iPad 1 + 最大硬件音频采样率