首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在定制文本绘图过程中,构造NSParagraphStyle的正确方法是什么?

在定制文本绘图过程中,构造NSParagraphStyle的正确方法是什么?
EN

Stack Overflow用户
提问于 2022-09-01 21:39:56
回答 1查看 71关注 0票数 -1

下面是用于在UICollectionViewCell中执行自定义文本绘图的代码。

代码语言:javascript
复制
//
// UICollectionViewCell
//
- (void)drawRect:(CGRect)rect
{
    [super drawRect:rect];

    ...
    
    NSParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];

    ...
    
    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
                                titleFont, NSFontAttributeName,
                                textColor, NSForegroundColorAttributeName,
                                style, NSParagraphStyleAttributeName,
                                nil];
    
    [string drawWithRect:centeredTextRect options:options attributes:attributes context:nil];

    ...

    NSDictionary *subtitleAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
                                        subtitleFont, NSFontAttributeName,
                                        textColor, NSForegroundColorAttributeName,
                                        style, NSParagraphStyleAttributeName,
                                        nil];

    [self.subtitle drawWithRect:subtitleCenteredTextRect options:options attributes:subtitleAttributes context:nil];
}

我对以下几条线没有信心,尽管它似乎有效。

代码语言:javascript
复制
NSParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];

它应该是

代码语言:javascript
复制
NSParagraphStyle *style = NSMutableParagraphStyle.defaultParagraphStyle;

代码语言:javascript
复制
NSParagraphStyle *style = NSMutableParagraphStyle.defaultParagraphStyle.mutableCopy;

我应该把style作为成员变量,这样我只需要构造1次NSParagraphStyle,并在drawRect中多次使用它?(但是,将NSParagraphStyle作为成员变量放置是否安全,因为NSParagraphStyle是一个可变项?)

EN

回答 1

Stack Overflow用户

发布于 2022-09-02 12:03:53

应该是

NSMutableParagraphStyle.defaultParagraphStyle;= NSParagraphStyle *style

这段代码对我来说没什么意义。defaultParagraphStyle属性在NSParagraphStyle类中定义,在NSMutableParagraphStyle接口中不(公开)覆盖。此外,在NSParagraphStyle接口中,对该属性的开发人员评论说,它是一个共享实例:

此类属性返回具有默认样式设置的共享和缓存的NSParagraphStyle实例,其值与[[NSParagraphStyle alloc] init]的结果相同。

因此,我希望NSMutableParagraphStyle.defaultParagraphStyle实例不仅是相等的,而且是从NSParagraphStyle.defaultParagraphStyle返回的完全相同的实例

代码语言:javascript
复制
NSParagraphStyle *style = NSParagraphStyle.defaultParagraphStyle;
NSMutableParagraphStyle *mutableStyle = NSMutableParagraphStyle.defaultParagraphStyle;
// style and mutableStyle instance refer to the same address
mutableStyle.lineSpacing = 20; // unrecognized selector runtime error

NSMutableParagraphStyle.defaultParagraphStyle.mutableCopy;= NSParagraphStyle *style

这里的问题是,当您需要一个defaultParagraphStyle实例时,使用NSMutableParagraphStyle只是多余的。当您需要一个可变的实例时,为什么要引用不可变的实例?直接实例化就行了。

NSParagraphStyle *style = [NSMutableParagraphStyle alloc init];

还不清楚为什么要用可变对象初始化指向不可变对象的指针。如果您计划稍后将其转换为更改数据,那么它实际上并不是一致的。我建议创建一个NSMutableParagraphStyle变量并按照设计来使用它。

至于它是否应该是类的实例变量/属性(而不是局部变量),我认为它没有什么问题,只要:

您的代码是single-threaded

  • You,不要将您的NSMutableParagraphStyle *实例变量传递给其他实例来存储。

至于第二点,我指的是这样的代码:

代码语言:javascript
复制
NSMutableParagraphStyle *mutableStyle = [NSMutableParagraphStyle new];
NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:@"MyString" attributes:@{
    NSParagraphStyleAttributeName: mutableStyle
}];

attrString是不可变类NSAttributedString的一个实例,但是它在这里使用mutableStyle,在这段代码之后的任何一点上都可以很容易地进行更改。

我确信NSAttributedString实现实际上负责处理这样的场景,并对传递的字典中的属性进行不变的复制,但是由于您实现了您自己的类(它可能会存储NSParagraphStyle *的一个实例),您应该知道,如果您设计了一种方法来使用类之外的值(通过属性或构造函数)初始化它,那么您应该意识到最好存储这样一个实例的副本。

如果属性是NSMutableParagraphStyle类型的,那么问题并不复杂(不可变的版本是超类,因此不能在没有编译器警告的情况下使用),但我仍然会复制以避免意外的突变。

TLDR:用以下方法初始化实例:

代码语言:javascript
复制
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];

或使用具有复制或/和只读属性的属性存储它:

代码语言:javascript
复制
@property(copy, readonly, nonatomic) NSMutableParagraphStyle *style;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73575684

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档