Dose objc_release / objc_retain 线程安全吗?
Dose objc_release / objc_retain thread safe?
一个Class属性,如:
@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
}
主要thread:Only阅读属性
后台线程:写入属性内容
这个线程安全吗?
看了一些源码后,我还有一个问题是:
objc_retain 和 objc_release 相同的对象是线程安全的吗?
正如 Petesh 指出的那样,这个问题大部分在 thread-safe retain/release 中得到了回答,但我认为只是在那里重复会错过回答您的具体问题。
您已明确要求此 属性 不是 是线程安全的:
@property (nonatomic, copy) NSString *testStr;
默认行为是atomic
,这使得在不同线程上读写指针(不改变对象)是安全的。您已标记此 nonatomic
,这会禁用该行为。有关这方面的更多信息,请参阅 atomic
.
上的 bbum 相当 canonical answer
不过,您的代码也是一个很好的例子,它说明了仅依靠原子读取来使代码“线程安全”是如何出错的。此行非常不安全:
if ((!model.testStr || ![model.testStr isKindOfClass:[NSString class]] || model.testStr.length == 0)) {
这使得 model.testStr
的三个独立读取。即使使用 atomic
,如果您可能在另一个线程上修改它,也不能保证它们是同一个对象。您测试 class 的事实表明 testStr
可能不是 NSString。如果是这样,那么 model.testStr.length
可能会因“不响应选择器”而崩溃。如果您在 if
块内使用 model.testStr
,那么它也可能与您测试的值不同。
一个Class属性,如:
@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
}
主要thread:Only阅读属性
后台线程:写入属性内容
这个线程安全吗?
看了一些源码后,我还有一个问题是: objc_retain 和 objc_release 相同的对象是线程安全的吗?
正如 Petesh 指出的那样,这个问题大部分在 thread-safe retain/release 中得到了回答,但我认为只是在那里重复会错过回答您的具体问题。
您已明确要求此 属性 不是 是线程安全的:
@property (nonatomic, copy) NSString *testStr;
默认行为是atomic
,这使得在不同线程上读写指针(不改变对象)是安全的。您已标记此 nonatomic
,这会禁用该行为。有关这方面的更多信息,请参阅 atomic
.
不过,您的代码也是一个很好的例子,它说明了仅依靠原子读取来使代码“线程安全”是如何出错的。此行非常不安全:
if ((!model.testStr || ![model.testStr isKindOfClass:[NSString class]] || model.testStr.length == 0)) {
这使得 model.testStr
的三个独立读取。即使使用 atomic
,如果您可能在另一个线程上修改它,也不能保证它们是同一个对象。您测试 class 的事实表明 testStr
可能不是 NSString。如果是这样,那么 model.testStr.length
可能会因“不响应选择器”而崩溃。如果您在 if
块内使用 model.testStr
,那么它也可能与您测试的值不同。