V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
iOS 开发实用技术导航
NSHipster 中文版
http://nshipster.cn/
cocos2d 开源 2D 游戏引擎
http://www.cocos2d-iphone.org/
CocoaPods
http://cocoapods.org/
Google Analytics for Mobile 统计解决方案
http://code.google.com/mobile/analytics/
WWDC
https://developer.apple.com/wwdc/
Design Guides and Resources
https://developer.apple.com/design/
Transcripts of WWDC sessions
http://asciiwwdc.com
Cocoa with Love
http://cocoawithlove.com/
Cocoa Dev Central
http://cocoadevcentral.com/
NSHipster
http://nshipster.com/
Style Guides
Google Objective-C Style Guide
NYTimes Objective-C Style Guide
Useful Tools and Services
Charles Web Debugging Proxy
Smore
kobe1941
V2EX  ›  iDev

CoreText 进行图文混排时卡了主线程求破

  •  
  •   kobe1941 · 2015-07-20 10:55:56 +08:00 · 4955 次点击
    这是一个创建于 3406 天前的主题,其中的信息可能已经有所发展或是发生改变。
    题主在使用CoreText控件进行图文混排。图片主要是自定义的表情,尺寸比一般文字的高度要大一些,所以在计算该控件的高度时,每次都需要生成ctFrame然后遍历每一行判断该行是否有表情图片,来累加计算该控件的高度。然后卡主了主线程,通过debug已找到卡主线程的原因就在于这个控件计算高度时每次都创建ctFrame这一个环节,求助V友,有什么方法可以简化计算高度的方法吗?

    由于是表情图片,比系统的emoji尺寸大,所以我才每次都会去创建ctFrame进行遍历的。

    补充:并不是每次发表情图片都会卡,是当用户一次性发几十个表情时,会卡住,且卡在控件计算高度那里,并不是drawRect绘制方法里。
    20 条回复    2015-07-21 09:53:46 +08:00
    nullcc
        1
    nullcc  
       2015-07-20 11:20:52 +08:00
    没看过你的代码不是很清楚,参考我以前写的这方面的代码,计算高度的时候创建的typesetter要记得CFRelease掉,另外要在主线程里setNeedsDisplay。
    wdxz5586
        2
    wdxz5586  
       2015-07-20 11:21:45 +08:00   ❤️ 1
    CoreText 和 CoreGraphics 都是线程安全的,可以不在主线程做排版和渲染。AsyncDisplayKit 很优雅地封装了这种操作,可以参考参考。
    kobe1941
        3
    kobe1941  
    OP
       2015-07-20 11:30:06 +08:00
    @nullcc 你以前的代码在哪里?能给个链接吗
    nullcc
        4
    nullcc  
       2015-07-20 11:32:30 +08:00
    @kobe1941 公司的代码,可能不大方便给出,不过 @wdxz5586 说的提醒我了,确实是这样。
    nullcc
        5
    nullcc  
       2015-07-20 11:36:09 +08:00
    唐巧有写过一个coretext排版引擎,开源的,可以参考下
    yfmir
        6
    yfmir  
       2015-07-20 11:55:49 +08:00
    可以尝试UILabel + NSAttributedString
    chmlai
        7
    chmlai  
       2015-07-20 12:05:48 +08:00
    简单的就是在后台把要显示的东西绘制到一个图片上去然后 dispatch 到UI 线程显示图片就行了.
    joeytat
        8
    joeytat  
       2015-07-20 12:23:18 +08:00
    只是表情的话,NSAttributedString + NSTextAttachment 就可以了。之前撸过一个类似的小东西 https://github.com/joeytat/JTATEmoji
    kobe1941
        9
    kobe1941  
    OP
       2015-07-20 12:57:32 +08:00
    @joeytat
    @yfmir 是自定义表情,不是系统表情,所以必须自己重绘。
    kobe1941
        10
    kobe1941  
    OP
       2015-07-20 12:58:35 +08:00
    @wdxz5586
    @nullcc 正在研究AsyncDisplayKit,感谢两位,唐巧的教程看过了,没讲优化,只解释了基本绘制原理。
    kobe1941
        11
    kobe1941  
    OP
       2015-07-20 12:59:40 +08:00
    @chmlai 绘制到UIView之前要先根据数据计算该控件的高度,我就卡在这里,还在研究ing
    qq2511296
        12
    qq2511296  
       2015-07-20 13:02:38 +08:00   ❤️ 1
    @kobe1941 自定义表情也可以用NSTextAttachment 就一张小图片而已 NSTextAttachment可以插入图片
    ibremn
        13
    ibremn  
       2015-07-20 13:55:00 +08:00
    所有能后台线程完成的操作,都放到后台线程去做。

    拿显示微博举个例子:
    1.发起网络请求,开始转圈圈。
    2. 获取到JSON数据后,在后台线程里解析成数据模型,随后创建CoreText对象、计算每个Cell的高度,保存到一个中间模型去(比如每个 Cell 对应一个 CellLayout)。
    3.停止转圈圈,更新 TableView。
    4.在 Cell 需要更新时,传入 CellLayout 来显示。
    5.在需要绘制文本时,先清空文本 label.layer.contents, 在后台线程创建 BitmapContext,用CoreText绘制为图片,然后转到主线程来把图片更新到 label.layer.contents 去。

    或者。。直接用 AsyncDisplayKit 吧。。原理类似。。
    kobe1941
        14
    kobe1941  
    OP
       2015-07-20 14:49:23 +08:00
    @ibremn 感谢大神,我按照你的思路继续研究。
    目测活捉某浪工程师一枚?
    zythum
        15
    zythum  
       2015-07-20 15:00:56 +08:00
    @ibremn 下次用微信举例子....
    ibremn
        16
    ibremn  
       2015-07-20 15:27:42 +08:00
    @kobe1941 咦?举个例子而已,我又不是渣浪的 ╮( ̄▽ ̄")╭
    kobe1941
        17
    kobe1941  
    OP
       2015-07-20 15:34:17 +08:00
    @ibremn 好吧,不过引出一枚某浪工程师 @zythum
    loveuqian
        18
    loveuqian  
       2015-07-20 15:44:01 +08:00 via iPhone
    今天才刚学自定义cell。。。
    joeytat
        19
    joeytat  
       2015-07-20 22:57:51 +08:00
    @kobe1941 我发的 git repo 链接里面就是自定义表情的实现啊,iOS 又没有 QQ 表情……
    kobe1941
        20
    kobe1941  
    OP
       2015-07-21 09:53:46 +08:00
    @joeytat 好,我研究研究,多谢
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3690 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 04:26 · PVG 12:26 · LAX 20:26 · JFK 23:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.