Rud*_*lis 4 objective-c grand-central-dispatch
我阅读了关于GCD队列的Apple文档,并开始想知道如果我想修改一个NSMutableArray在串行队列中不是线程安全的类型的实例成员会发生什么?串行队列将保证我连续执行操作,但我仍然觉得我需要执行一个@syncrhonized块或其他技术来强制内存屏障,因为据我所知,我的串行队列上的任务可以被调用不同的线程.那是对的吗?这是一个简单的例子:
@interface Foo : NSObject
-(void)addNumber:(NSNumber*)number;
-(void)printNumbers;
-(void)clearNumbers;
@end
@implementation Foo
{
dispatch_queue_t _queue;
NSMutableArray<NSNumber*>* _numbers;
}
-(instancetype)init
{
if (self = [super init])
{
_queue = dispatch_queue_create(NULL, NULL);
_numbers = [NSMutableArray array];
}
return self;
}
-(void)addNumber:(NSNumber*)number
{
dispatch_async(_queue,
^{
[_numbers addObject:number];
});
}
-(void)printNumbers
{
dispatch_async(_queue,
^{
for (NSNumber* number in _numbers)
{
NSLog(@“%@“, number);
}
});
}
-(void)clearNumbers
{
dispatch_async(_queue,
^{
_numbers = [NSMutableArray array];
});
}
@end;
Run Code Online (Sandbox Code Playgroud)
据我所知,如果我从任意线程调用成员方法,我可能会遇到内存问题?或者GCD在引擎盖下提供了一些保证,为什么我不需要强制记忆障碍?看看这些例子,我没有在任何地方找到这样的结构,但是从C++开始,在锁定下触摸成员变量是有意义的.
如果您的队列是一个串行队列,它将只允许一次一个操作,无论它在哪个线程上运行.因此,如果每次访问资源都发生在队列中,则无需使用锁或信号量进一步保护该资源.事实上,可以使用调度队列作为锁定机制,对于某些应用程序,它可以很好地工作.
现在,如果您的队列是并发队列,那么这是一个不同的故事,因为多个操作可以在并发队列上同时运行.但是,GCD提供了API dispatch_barrier_sync和dispatch_barrier_asyncAPI.通过这两个函数调用启动的操作将导致队列在执行块之前等待所有其他操作完成,然后在块完成之前禁止运行任何其他操作.通过这种方式,它可以暂时使队列的行为类似于串行队列,甚至允许并发队列用作一种锁定机制(例如,允许通过正常dispatch_sync调用读取资源,但通过dispatch_barrier_async.如果读取非常频繁地发生并且写入很少,那么这可以很好地执行.
| 归档时间: |
|
| 查看次数: |
387 次 |
| 最近记录: |