滚动UICollectionView会占用大量内存导致崩溃

时间:2015-04-15 16:18:05

标签: ios memory-leaks uicollectionview uilabel uicollectionviewcell

我正在开发一个表情符号键盘。这是我的方法:

  • 我决定使用UICollectionView。我在代码中执行所有操作,并且不打算使用Xib文件。
  • 我创建了UICollectionViewCell的子类。这将包含一个显示表情符号的标签。这是我在initWithFrame中做的事情

    - (instancetype)initWithFrame:(CGRect)frame {
        self = [super initWithFrame:frame];
        if (self) {
            if (_label == nil) {
            _label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
    
            _label.autoresizingMask = (UIViewAutoresizingFlexibleWidth |
                                       UIViewAutoresizingFlexibleHeight);
    
            _label.textAlignment = NSTextAlignmentCenter;
            [_label setNumberOfLines:1];
            self.contentView.layer.cornerRadius = 6.0;
    
            [self.contentView addSubview:_label];
            }
        }
    
        return self;
    }
    
  • 在UICollectionView dataSource对象中,我读取了一个包含NSDictionary的plist文件,其中NSString为键,NSArrays为值。在每个NSArray中,人们可以找到我要展示的表情符号。然后我将字典存储在属性中。这是代码:

    @property (nonatomic, strong) NSDictionary *emojis;
    
    - (NSDictionary *)emojis {
         if (!_emojis) {
              NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"EmojisList"
                                                          ofType:@"plist"];
             _emojis = [NSDictionary dictionaryWithContentsOfFile:plistPath];
        }
        return _emojis;
    }
    
  • 在以下方法中,我尝试填充单元格:

    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    
            NSString *cellIdentifier = @"Cell";
    
            EmojiCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
            cell.label.font = [UIFont systemFontOfSize:self.isiPad ? 47 : 33];
    
            NSArray *dataArray = [self.emojis objectForKey:self.categoryNames[indexPath.section]];
            cell.label.text = dataArray[indexPath.row];
    
            return cell;
    }
    

我遇到的问题是滚动时内存使用量增加了。这会导致真实设备崩溃。

请帮帮我。我测试了许多不同的方法来解决这个问题,但我没有成功。

这是乐器的截图。我真的不知道那些是什么。

Memory Usage increases when I scroll

6 个答案:

答案 0 :(得分:1)

字体大小做技巧。

“Apple Color Emoji”字体根据字体大小将表情符号替换为不同大小的PNG图像。较大的图像很快会占用40MB的内存限制。

在我的情况下,我尝试使用16的字体大小并使用1.5比例变换使其足够大。结果看起来并不好,但至少它有效...

答案 1 :(得分:0)

您可能希望在滚动时将UIViewCells和内容从内存中卸载,这些单元格不在屏幕上。 UICollectionView应该这样做,但我会仔细检查。

你能分享你的collectionView作品的代码吗?

答案 2 :(得分:0)

我不确定实际分配了多少内存,但由于集合视图,它确实不会崩溃。但是,要意识到键盘,尤其是在iPhone 6+上运行的键盘,仅限于相当小的内存占用。因此,显示包含许多子视图的大量单元格可能会导致内存问题。

但是,我假设这是由于保留周期。两个类很可能强烈地相互捕获。这可能发生在任何类型的块或两个相互引用的强大属性中。

当你无法追踪这种情况时,它可能是最简单的方法来缩小它可能造成的代码。 例如,不要从plist加载表情符号来检查代码是否影响它。

我希望这会有所帮助,如果不查看整个项目,基本上无法判断。

答案 3 :(得分:0)

每次加载单元格时,您是否正在从磁盘读取plist?如果是这样的话,每次加载一个单元格时,你可能正在将plist读入内存,并且它不会再被释放。尝试禁用读取plist的代码(暂时在数组中放入一些测试字符串),看看是否有帮助。如果是这样,那就是问题所在。

答案 4 :(得分:0)

我有同样的问题, 好吧,仍然存在问题,但......

我发现当我使用transform而不是UIFont.size时,它会大大减少内存使用量。

答案 5 :(得分:0)

尝试设置标签的不透明是