拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 剂量objc_release/objc_retain执行绪安全吗?

剂量objc_release/objc_retain执行绪安全吗?

白鹭 - 2022-02-22 2152 0 0

类属性,例如:

@interface TestModel
@property (nonatomic, copy) NSString *testStr;
@end 

在主执行绪:

for (model in modellist) {
    if ((!model.testStr || ![model.testStr isKindOfClass:[NSString class]] || model.testStr.length == 0)) {
         NSLog(@"empty str");
    }
    NSLog(@"not empty str");
}

在后台执行绪:

for (model in modellist) {
    model.testStr = anotherStringFromAlloc
}

在主执行绪:只读取属性

在后台执行绪:写入属性内容

这个执行绪安全吗?

在阅读了一些源代码之后,我还有一个问题是: 将 objc_retain 和 objc_release 相同的 obj 设为执行绪安全吗?

uj5u.com热心网友回复:

正如 Petesh 所指出的,这个问题主要是在执行绪安全的 retain/release 中回答的,但我认为只是在那里重复会错过回答你的具体问题。

您已明确要求此属性不是执行绪安全的:

@property (nonatomic, copy) NSString *testStr;

默认行为是atomic,这使得在不同执行绪上读取和写入指标(而不是改变物件)是安全的。您已标记 this nonatomic,这会禁用该行为。欲了解更多关于此,请参阅bbum的相当经典的答案atomic

不过,您的代码也是一个很好的例子,说明仅依靠原子读取来使代码“执行绪安全”可能会出错。这条线非常不安全:

if ((!model.testStr || ![model.testStr isKindOfClass:[NSString class]] || model.testStr.length == 0)) {

这使得三个单独的读取model.testStr即使使用atomic,如果您可以在另一个执行绪上修改它,也不能保证它们是同一个物件。您测验该类的事实表明它testStr可能不是 NSString。如果是这样,那么model.testStr.length可能会因“不回应选择器”而崩溃。如果您model.testStrif使用,那么这也可能与您测验的值不同。

标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *