如何清除填充表情符号字符的字体缓存?

Ras*_*sto 22 fonts caching memory-management ios emoji

我正在为iPhone开发键盘扩展.苹果自己的表情符号键盘有一个表情符号屏幕,显示了大约800个表情符号字符UICollectionView.

UIScrollView滚动此表情符号时,内存使用量会增加而不会下降.我正在重复使用单元格,当使用显示800次的单个表情符号字符进行测试时,内存在滚动期间不会增加.

使用工具我发现我的代码中没有内存泄漏,但似乎表情符号字形被缓存,并且根据字体大小可以占用大约10-30MB的内存(研究显示它们实际上是PNG).键盘扩展可以在被杀之前使用很少的内存.有没有办法清除字体缓存?


编辑

添加代码示例以重现问题:

let data = Array("????????????????????????????????????").map {String($0)}

class CollectionViewTestController: UICollectionViewController {
    override func viewDidLoad() {
        collectionView?.registerClass(Cell.self, forCellWithReuseIdentifier: cellId)
    }

    override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return data.count
    }

    override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(cellId, forIndexPath: indexPath) as! Cell
        if cell.label.superview == nil {
            cell.label.frame = cell.contentView.bounds
            cell.contentView.addSubview(cell.label)
            cell.label.font = UIFont.systemFontOfSize(34)
        }
        cell.label.text = data[indexPath.item]
        return cell
    }

    override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        return 1
    }
}

class Cell: UICollectionViewCell {
    private let label = UILabel()
}
Run Code Online (Sandbox Code Playgroud)

在运行并滚动后,UICollectionView我得到了内存使用情况图,如下所示: 在此输入图像描述

Mat*_*hew 11

我遇到了同样的问题并通过从/ System/Library/Fonts/Apple Color Emoji.ttf转储.png并使用UIImage(contentsOfFile:String)而不是String来修复它.

我使用https://github.com/github/gemoji提取.png文件,用@ 3x后缀重命名文件.

func emojiToHex(emoji: String) -> String {
    let data = emoji.dataUsingEncoding(NSUTF32LittleEndianStringEncoding)
    var unicode: UInt32 = 0
    data!.getBytes(&unicode, length:sizeof(UInt32))
    return NSString(format: "%x", unicode) as! String
}

let path = NSBundle.mainBundle().pathForResource(emojiToHex(char) + "@3x", ofType: "png")
UIImage(contentsOfFile: path!)
Run Code Online (Sandbox Code Playgroud)

UIImage(contentsOfFile:path!)被正确释放,因此内存应该保持在低水平.到目前为止,我的键盘扩展尚未崩溃.

如果UIScrollView包含大量表情符号,请考虑使用UICollectionView,它只在缓存中保留3或4页,并释放其他看不见的页面.

  • 是的,这是我的备用计划.它有一些dowsides低谷:那些.PNG将增加应用程序下载大小大约15 MB,我将在我的项目中有大约800个额外的文件,一些额外的工作,我认为不应该是必要的... (2认同)
  • 通过适当的png压缩,我认为您可以将额外的大小减少到大约4MB.我同意它不应该是必要的,不幸的是,除非Apple修复此问题,否则我看不到任何其他选项...... (2认同)
  • 我使用Adobe Fireworks批处理作业来压缩我的图像,但我猜任何其他图像软件都可以这样做.您可以将图像限制为256色以减小尺寸.我个人认为与原版表情符号没什么区别. (2认同)

Ewa*_*lor 1

我猜测您正在使用[UIImage imageNamed:]或源自它的东西加载图像。这会将图像缓存在系统缓存中。

您需要使用[UIImage imageWithContentsOfFile:]以下命令来加载它们。这将绕过缓存。

(如果这不是问题,那么您需要在问题中包含一些代码,以便我们可以看到发生了什么。)