滚动UICollectionView使用大量的内存导致崩溃

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

  • 我决定使用UICollectionView。 我在代码中做所有事情,不打算使用Xib文件。
  • 我创build了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对象中,我读取一个plist文件,其中包含一个NSDictionary,NSString为键,NSArrays为值。 在每个NSArray内,可以find我要展示的表情符号。 然后我把这本字典存放在一个属性中。 这里是代码:

     @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; } 

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

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

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

内存使用增加,当我滚动

字体大小做伎俩。

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

在我的情况下,我尝试了16的字体大小,并使用1.5尺度转换,使其足够大。 结果看起来不错,但至less它工作…

当您滚动时,您可能需要将UIViewCells和内容卸载到内存之外,并且这些单元格不在屏幕上。 UICollectionView应该这样做,但我会仔细检查。

你可以分享你的代码为collectionView片?

我不确定有多less内存是真正分配的,但它确实不应该因收集视图而崩溃。 但是,要意识到键盘(特别是在iPhone 6+上运行)仅限于相当小的内存空间。 有很多子视图显示的单元格可能会导致类似的内存问题。

不过,我假设这是由于保留周期。 两个class最有可能强烈地相互吸引。 这可能发生在任何types的块或两个强相关的引用。

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

我希望这可以帮助,基本上不可能不通过整个项目。

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

我真的有同样的问题,那么,仍然是问题剩下,但….

我发现,当我使用转换,而不是UIFont.size,它会减less内存使用相当多。

尝试设置标签的不透明是