在不同的线程上调用的类的实例方法是否可以使用该类的属性?

时间:2015-01-11 20:28:37

标签: ios objective-c multithreading macos

我几天来一直在我的应用程序中研究和调试这个问题,但我仍然无法得到答案。所以我认为最好只问问题。我们走了......

假设我们在主线程上创建了一个类的实例,但是使用dispatch_async将该类的一个方法的调用放在另一个线程上。如果该方法使用类中的属性,那么它是否是线程安全的(类实例是在主线程上创建的。当然,访问属性将是跨线程的。)?一个例子是:

@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];
});

我的app中有一个访问属性的类中有一个递归方法。只是该方法意味着在不同的线程上调用,所以不要阻止UIKit线程。但是,当方法执行时,内存只会以每秒30MB的速度攀升!我认为这与泄漏和多线程有关,但我似乎无法找到仪器中的泄漏。所以我在这里询问访问这样的属性是否是线程安全的。

如果我的问题很难理解,我很抱歉,我不是母语人士:)。谢谢您的光临。

1 个答案:

答案 0 :(得分:1)

在一般情况下,如果使用某些同步机制(如锁,障碍或串行队列),则只能获得线程安全性。有可能一个简单的数据值在没有同步的情况下是安全的,但这是不确定的,因为处理器(编译器?)可能决定缓存值而不是立即将它们写入内存。

对象和线程本质上是不相关的概念。每个方法都在某个线程上执行,但这对其他方法执行的线程没有影响。这包括构造函数。

对于像你这样的情况,使用命名并发队列访问属性,dispatch_sync从中读取,dispatch_barrier_async写入它是一个很有吸引力的想法。

这里有一个很好的讨论:https://www.mikeash.com/pyblog/friday-qa-2011-10-14-whats-new-in-gcd.html标题下的#34;自定义并发队列和障碍"。