Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 如果方法已在串行队列中执行,是否需要使用锁?_Objective C_Locking_Ipc_Grand Central Dispatch_Dispatch Async - Fatal编程技术网

Objective c 如果方法已在串行队列中执行,是否需要使用锁?

Objective c 如果方法已在串行队列中执行,是否需要使用锁?,objective-c,locking,ipc,grand-central-dispatch,dispatch-async,Objective C,Locking,Ipc,Grand Central Dispatch,Dispatch Async,我的库中公开了2个方法调用,如下所示: -(void) createFile { dispatch_async(serialQueue, ^{ [fileObj createFile:fileInfo completion:^(void){ //completion block C1 }]; }); } -(void) readFile:(NSUInteger)timeStamp { dispatch_async(s

我的库中公开了2个方法调用,如下所示:

-(void) createFile {
    dispatch_async(serialQueue, ^{
        [fileObj createFile:fileInfo completion:^(void){
           //completion block C1 
        }];
   });
}

-(void) readFile:(NSUInteger)timeStamp {
    dispatch_async(serialQueue, ^{
        [fileObj readFile:timeStamp completion:^(void){
           //completion block C2 
        }];
   });
}
现在,
createFile:fileInfo:completion
readFile:timeStamp:completion
依次是XPC调用,它们调用进程
P1
。它们在流程P1中的实现如下所示:

@interface FileObject : NSObject

+ (instancetype) sharedInstance;

@property (nonatomic, strong) NSData *fileContents;

@end

@implementation FileObject

+ (instancetype)sharedInstance
{
    static FileObject *sharedObj = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedObj = [[self alloc] init];
    });
    return sharedObj;
}

- (void)createFile:(FileInfo *)fileInfo
          completion:(void (^))completion {

          FileObject *f = [FileObject sharedInstance];
          //lock?
          f.fileContents = //call some method;
          //unlock         
    }

- (void)readFile:(NSUInteger)timeStamp
      completion:(void (^))completion {

    FileObject *f = [FileObject sharedInstance];

     //do stuff with f.fileContents
}
@end
需要注意的是,对方法
createFile
的调用能够修改单例obj,并且
readFile:fileInfo
总是在
createFile
之后调用(调用时使用串行队列)

我的问题是我的库中公开的两种方法的串行队列用法

  • readFileInfo:FileInfo:completion
    中修改
    f.fileContents
    时,是否仍需要锁定和解锁
  • 如果有多个不同的进程调用我的库呢?XPC to
    P1
    会自动处理这个问题吗,还是我应该对此做些什么
  • 你问:

    如果方法已在串行队列中执行,是否需要使用锁

    如果可以同时从多个线程与非线程安全对象交互,那么可以使用锁(或其他各种技术)来同步访问。但是,如果您从串行队列执行所有交互,则不需要锁

    但您需要小心,因为尽管您使用的是串行队列,但您有可能在不同线程上运行的完成处理程序。但是,如果您协调这些完成处理程序上的交互,以便任何一个都不能同时运行(下面将详细介绍),那么就不需要锁(或其他同步技术)

    基于您的代码片段(以及我们在其他地方进行的对话)的一系列其他想法:

  • 您仍然使用GCD调度调用和异步方法。这是一种认知失调。或者

    • 完全丢失调度队列并使用完成处理程序模式(这是更好的解决方案,但您说您不能更改端点,这显然排除了这种更符合逻辑的方法);或
    • 使
      createFile
      readFile
      行为同步(例如,使用信号量),然后您就可以利用GCD队列行为(我们通常避免锁、信号量或任何将“等待”的模式,但考虑到您在后台队列上执行此操作,问题较少)
  • 如果您想让这两个基本异步任务同步运行,也可以使用锁来实现,但我认为如果您要使用调度队列,调度信号量更符合逻辑模式

  • 更好的模式是使
    createFile
    readFile
    创建自定义、异步、
    NSOperation
    子类。这是一种比GCD中的锁或信号量强得多的模式,因为它将死锁风险降至最低

  • 与这里的问题完全无关,我不建议将
    FileObject
    设置为单例。每个
    FileObject
    都与一个特定的文件相关联,它不必成为一个单独的文件。这一点尤其重要,因为我们发现离线时您正在考虑这是一个包含多个请求的XPC服务,而单例模式与此相反

    另外,顺便说一句,
    FileObject
    不符合使用单例的基本标准。关于单例的考虑因素的讨论(我们不需要在这里重复,特别是因为它与您的主要问题无关),请参见单例有其位置,但这是一个您可能需要单独实例的场景,因此单例模式似乎特别不适合