ios - 在不同线程上调用的类的实例方法可以使用类的属性吗?

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

我的应用程序中的一个类中确实有一个访问属性的递归方法。只是那个方法应该在不同的线程上调用,所以不会阻塞 UIKit 线程。但是,当方法执行时,内存一直以每秒 30MB 的速度攀升!我认为这与泄漏和多线程有关,但我似乎无法在 Instruments 中找到泄漏。所以我在这里想问问这样访问属性是否是线程安全的。

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

最佳答案

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

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

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

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

关于ios - 在不同线程上调用的类的实例方法可以使用类的属性吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27891722/

相关文章:

multithreading - 如何在线程内接收 WM_POWERBROADCAST?

iOS "widget"风格界面

iphone - 返回时取消选择 TableView 行

iphone - 添加新按钮时旧按钮消失

ios - 方法 cellForRowAtIndexPath 未从方法 shouldChangeCharactersInRange 中调用

java - 分布式 Spring REST 服务中的线程安全

multithreading - 多个请求访问同一个 web 方法

ios - AVCaptureVideoPreviewLayer 方向 - 需要横向

ios - 如何使用 NSFetchedResultsController 和多个获取的实体设置 collectionView(或 TableView)

ios - 自动调整表格 View