gpt4 book ai didi

ios - Objective-C 类别中的线程安全

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:54:25 25 4
gpt4 key购买 nike

我在 NSString 上有一个类别:

- (CGSize) agb_sizeWithFont:(UIFont *)font width:(CGFloat)width lineBreakMode:(NSLineBreakMode)lineBreakMode {
if (!font) return CGSizeZero;

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineBreakMode = lineBreakMode;
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, paragraphStyle, NSParagraphStyleAttributeName, nil];

// this line is not threadsafe
NSAttributedString *as = [[NSAttributedString alloc] initWithString:self attributes:attributes];

CGRect bounds = [as boundingRectWithSize:CGSizeMake(width, 10000) options:(NSStringDrawingUsesLineFragmentOrigin) context:nil];
return CGSizeMake(width, bounds.size.height);
}

我观察到在多个线程上运行此代码时间歇性的 EXC_BAD_ACCESS 崩溃(有时在 initWithString: attributes: 中,有时在 boundingRectWithSize:options:context: )。

我相信我的代码不是线程安全的,因为 self 可能会在一个线程上释放,而 initWithString: attributes: 正在另一个线程上执行。

  1. 我关于此方法的线程安全性的结论是否正确?
  2. 这段代码会使其成为线程安全的吗?

    NSString *strongSelf = self;
    NSAttributedString *as = [[NSAttributedString alloc] initWithString:strongSelf attributes:attributes];

    (通过维护对 self 的引用,我试图确保内存中的对象在我使用它时不会被释放。)

  3. 有什么方法可以将此方法声明为非线程安全?我很乐意生成警告,例如,如果将声明为 nonatomic 属性的字符串传递到此方法中。

注意:如果不是很明显,我使用的是 ARC。

最佳答案

任何 NSMutableString 也是一个 NSString。因此,您添加到类别中 NSString 的任何方法都可以在 NSMutableString 上调用。如果可变字符串可能同时在另一个线程上发生变化,那么在一个线程上操作可变字符串是不安全的。在另一个线程上读取可变字符串时,读取它是安全的。

由于您调用 -[NSAttributedString initWithString:attributes:] 是从字符串 self 中读取的,所以如果 self 这样做是不安全的是一个可变字符串,可能会同时在另一个线程上发生变化。

您可能想查看所有对 -agb_sizeWithFont:width:lineBreakMode: 的调用,以查看接收器的类型是否为 NSMutableString*。然而,这还不够。 NSMutableString 的实例可以由类型为 NSString* 的变量(或其他类似 NSObject*id),也是。

您将无法使 -agb_sizeWithFont:width:lineBreakMode: 线程安全,因此。线程安全不会分解。它必须被设计到管理它可能被调用的任何字符串的代码中。也就是说,所有接触给定字符串对象并可能调用您的方法并在其他地方可能对其进行修改的代码都必须负责确保一次只发生其中一件事情。

关于ios - Objective-C 类别中的线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21224483/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com