使用@synchronized与同步操作

时间:2016-03-25 17:59:50

标签: ios objective-c multithreading thread-safety

我正在使用一个UIDocument子类,它有可能从多个线程调用其saveToURL方法。因此我将它封装在一个包装器函数中,我想让线程安全:

- (void)saveWithCompletionBlock:(void(^)(TransactionDocumentReturnCode status))completion {
    @synchronized (self) {
        [self saveToURL:[self fileURL] forSaveOperation:UIDocumentSaveForOverwriting completionHandler:^(BOOL success){
            // Generate returncode depending on outcome of save operation
            completion(returncode);
        }];
    }
}

我假设对[self saveToURL:...]的调用将立即返回,因为保存操作本身发生在后台线程上,导致锁定在保存操作完成之前被释放。那么,有没有办法让其他线程调用saveWithCompletionBlock:被阻塞,直到saveToURL的完成块被调用?

1 个答案:

答案 0 :(得分:0)

我刚才想到的一个可能的解决方案是向我的UIDocument子类添加一个属性,以指示是否正在进行保存操作,如果是,则等待然后重试。在@synchronize中包装此属性的检查和设置应该可以防止两个线程同时将该值读取为false并且相信它们可以保存文档:

- (void)saveWithCompletionBlock:(void(^)(TransactionDocumentReturnCode status))completion {
    @synchronized(self){
        if (self.isSaving) {
            [self performSelector:@selector(saveWithCompletionBlock:) withObject:completion afterDelay:1.0];
            return;
        }

        self.isSaving = YES;
    }

    [self saveToURL:[self fileURL] forSaveOperation:UIDocumentSaveForOverwriting completionHandler:^(BOOL success){
        // Generate returncode depending on outcome of save operation
        completion(returncode);
        self.isSaving = NO;
    }];
}

我不知道这是否足够或被视为良好的多线程练习。