自定义文本绘制中NSParagraphStyle的正确构造方式及使用疑问
问题解答
关于段落样式的初始化选择
先明确几种写法的核心差异:
[[NSMutableParagraphStyle alloc] init]
这种写法会创建一个空的可变段落样式实例,但它的属性并非系统默认标准值(部分属性可能处于未定义状态),虽然看似能正常运行,但在不同iOS版本可能出现不一致的绘制效果,不推荐使用。NSMutableParagraphStyle *style = NSMutableParagraphStyle.defaultParagraphStyle;
这是错误写法:defaultParagraphStyle返回的是不可变的NSParagraphStyle实例,直接赋值给可变类型指针会触发编译警告,若后续尝试修改该实例属性,会直接导致运行时崩溃(不可变对象不允许修改)。NSMutableParagraphStyle *style = NSMutableParagraphStyle.defaultParagraphStyle.mutableCopy;
这是推荐的正确写法:先获取系统提供的默认段落样式(包含标准对齐、行间距等默认属性),再通过mutableCopy生成可变实例,你可以基于这个实例自定义修改需要的段落属性(比如文本居中、调整行间距等),既能保证初始属性符合系统规范,又支持个性化配置。
关于将样式设为成员变量的安全性
如果你的段落样式是固定不变的(所有cell的文本段落样式一致),可以将其缓存为成员变量,但要注意以下几点:
- 若使用可变的
NSMutableParagraphStyle作为成员变量,必须确保所有修改操作都在主线程执行(drawRect在主线程调用,UI操作必须遵循主线程规则),同时要避免其他代码意外修改这个可变对象,否则会导致绘制结果异常。 - 更安全的做法是:将配置好的可变样式转换为不可变的
NSParagraphStyle(调用copy方法),再将这个不可变实例作为成员变量缓存。不可变对象不存在被意外修改的风险,线程安全,且可以在drawRect中重复使用,避免每次绘制都创建新实例,提升性能。
示例代码(在cell初始化时缓存样式):
@interface MyCollectionViewCell () @property (nonatomic, strong) NSParagraphStyle *cachedParagraphStyle; @end @implementation MyCollectionViewCell - (void)awakeFromNib { [super awakeFromNib]; NSMutableParagraphStyle *mutableStyle = [NSMutableParagraphStyle.defaultParagraphStyle mutableCopy]; // 自定义配置段落属性 mutableStyle.alignment = NSTextAlignmentCenter; mutableStyle.lineSpacing = 4.0; // 转换为不可变实例缓存 self.cachedParagraphStyle = [mutableStyle copy]; } - (void)drawRect:(CGRect)rect { [super drawRect:rect]; // 直接复用缓存的不可变样式 NSDictionary *attributes = @{ NSFontAttributeName: titleFont, NSForegroundColorAttributeName: textColor, NSParagraphStyleAttributeName: self.cachedParagraphStyle }; [string drawWithRect:centeredTextRect options:options attributes:attributes context:nil]; // 副标题同理使用缓存样式 NSDictionary *subtitleAttributes = @{ NSFontAttributeName: subtitleFont, NSForegroundColorAttributeName: textColor, NSParagraphStyleAttributeName: self.cachedParagraphStyle }; [self.subtitle drawWithRect:subtitleCenteredTextRect options:options attributes:subtitleAttributes context:nil]; } @end
内容的提问来源于stack exchange,提问作者Cheok Yan Cheng
相关产品推荐
相关产品推荐

