在不同线程上调用的 class 的实例方法可以使用 class 的属性吗?
Could a class's instance method called on a different thread use the class's properties?
我已经在我的应用程序中研究和调试这个问题好几天了,但我仍然得不到答案。所以我认为最好只问这个问题。我们开始吧...
假设我们在主线程上创建了一个 class 的实例,但是使用 dispatch_async 将那个 class 的一个方法的调用放在另一个线程上。如果该方法使用 class 中的属性(class 实例是在主线程上创建的。访问这些属性肯定是跨线程的。),它会是线程安全的吗?一个例子是:
@interface AClass
@property (nonatomic) int blah; //Would it be more thread-safe if it is "atomic" instead?
- (void)foo;
@end
//Method implementation
- (void)foo {
self.blah++;
}
//dispatch_async on main thread
dispatch_async(dispatch_get_global_queue(...PRIORITY_BACKGROUND, 0), ^{
[aClassInstance foo];
});
我的应用程序中的一个 classes 确实有一个访问属性的递归方法。只是那个方法应该在不同的线程上调用,所以不会阻塞 UIKit 线程。但是,当方法执行时,内存一直以每秒 30MB 的速度攀升!我认为这与泄漏和多线程有关,但我似乎无法在 Instruments 中找到泄漏。所以我在这里问一下这样访问属性是否是线程安全的。
如果我的问题难以理解,我很抱歉,我不是母语人士:)。感谢您光临。
在一般情况下,只有使用某种同步机制(例如锁、屏障或串行 queues)才能获得线程安全。一个简单的数据值可能在没有同步的情况下是安全的,但这也不确定,因为处理器(编译器?)可能决定缓存值而不是立即将它们写入内存。
Objects和线程本质上是无关的概念。每个方法都在某个线程上执行,但这对其他方法执行的线程没有影响。这包括构造函数。
对于像您这样的情况,使用命名的并发 queue 访问 属性 并使用 dispatch_sync
读取它并 dispatch_barrier_async
写入它是一个吸引人的想法。
这里有一个很好的讨论:https://www.mikeash.com/pyblog/friday-qa-2011-10-14-whats-new-in-gcd.html 在标题 "Custom Concurrent Queues and Barriers" 下。
我已经在我的应用程序中研究和调试这个问题好几天了,但我仍然得不到答案。所以我认为最好只问这个问题。我们开始吧...
假设我们在主线程上创建了一个 class 的实例,但是使用 dispatch_async 将那个 class 的一个方法的调用放在另一个线程上。如果该方法使用 class 中的属性(class 实例是在主线程上创建的。访问这些属性肯定是跨线程的。),它会是线程安全的吗?一个例子是:
@interface AClass
@property (nonatomic) int blah; //Would it be more thread-safe if it is "atomic" instead?
- (void)foo;
@end
//Method implementation
- (void)foo {
self.blah++;
}
//dispatch_async on main thread
dispatch_async(dispatch_get_global_queue(...PRIORITY_BACKGROUND, 0), ^{
[aClassInstance foo];
});
我的应用程序中的一个 classes 确实有一个访问属性的递归方法。只是那个方法应该在不同的线程上调用,所以不会阻塞 UIKit 线程。但是,当方法执行时,内存一直以每秒 30MB 的速度攀升!我认为这与泄漏和多线程有关,但我似乎无法在 Instruments 中找到泄漏。所以我在这里问一下这样访问属性是否是线程安全的。
如果我的问题难以理解,我很抱歉,我不是母语人士:)。感谢您光临。
在一般情况下,只有使用某种同步机制(例如锁、屏障或串行 queues)才能获得线程安全。一个简单的数据值可能在没有同步的情况下是安全的,但这也不确定,因为处理器(编译器?)可能决定缓存值而不是立即将它们写入内存。
Objects和线程本质上是无关的概念。每个方法都在某个线程上执行,但这对其他方法执行的线程没有影响。这包括构造函数。
对于像您这样的情况,使用命名的并发 queue 访问 属性 并使用 dispatch_sync
读取它并 dispatch_barrier_async
写入它是一个吸引人的想法。
这里有一个很好的讨论:https://www.mikeash.com/pyblog/friday-qa-2011-10-14-whats-new-in-gcd.html 在标题 "Custom Concurrent Queues and Barriers" 下。