下面是用于在UICollectionViewCell中执行自定义文本绘图的代码。
//
// 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];
}我对以下几条线没有信心,尽管它似乎有效。
NSParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];它应该是
NSParagraphStyle *style = NSMutableParagraphStyle.defaultParagraphStyle;或
NSParagraphStyle *style = NSMutableParagraphStyle.defaultParagraphStyle.mutableCopy;或
我应该把style作为成员变量,这样我只需要构造1次NSParagraphStyle,并在drawRect中多次使用它?(但是,将NSParagraphStyle作为成员变量放置是否安全,因为NSParagraphStyle是一个可变项?)
发布于 2022-09-02 12:03:53
应该是
NSMutableParagraphStyle.defaultParagraphStyle;= NSParagraphStyle *style
这段代码对我来说没什么意义。defaultParagraphStyle属性在NSParagraphStyle类中定义,在NSMutableParagraphStyle接口中不(公开)覆盖。此外,在NSParagraphStyle接口中,对该属性的开发人员评论说,它是一个共享实例:
此类属性返回具有默认样式设置的共享和缓存的
NSParagraphStyle实例,其值与[[NSParagraphStyle alloc] init]的结果相同。
因此,我希望NSMutableParagraphStyle.defaultParagraphStyle实例不仅是相等的,而且是从NSParagraphStyle.defaultParagraphStyle返回的完全相同的实例
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
NSMutableParagraphStyle *实例变量传递给其他实例来存储。至于第二点,我指的是这样的代码:
NSMutableParagraphStyle *mutableStyle = [NSMutableParagraphStyle new];
NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:@"MyString" attributes:@{
NSParagraphStyleAttributeName: mutableStyle
}];attrString是不可变类NSAttributedString的一个实例,但是它在这里使用mutableStyle,在这段代码之后的任何一点上都可以很容易地进行更改。
我确信NSAttributedString实现实际上负责处理这样的场景,并对传递的字典中的属性进行不变的复制,但是由于您实现了您自己的类(它可能会存储NSParagraphStyle *的一个实例),您应该知道,如果您设计了一种方法来使用类之外的值(通过属性或构造函数)初始化它,那么您应该意识到最好存储这样一个实例的副本。
如果属性是NSMutableParagraphStyle类型的,那么问题并不复杂(不可变的版本是超类,因此不能在没有编译器警告的情况下使用),但我仍然会复制以避免意外的突变。
TLDR:用以下方法初始化实例:
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];或使用具有复制或/和只读属性的属性存储它:
@property(copy, readonly, nonatomic) NSMutableParagraphStyle *style;https://stackoverflow.com/questions/73575684
复制相似问题