【问题标题】:NSFileManager Thread SafeNSFileManager 线程安全
【发布时间】:2014-05-18 23:51:22
【问题描述】:

根据 Apple 的文档,NSFileManager 在执行基本文件操作时是线程安全的:

"共享的 NSFileManager 对象的方法可以安全地从多个线程调用。但是,如果您使用委托来接收有关移动、复制、删除和链接操作状态的通知,您应该创建一个唯一的实例文件管理器对象,将您的委托分配给该对象,并使用该文件管理器来启动您的操作。”

我一般怎样才能在后台线程上执行我的所有文件操作,同时仍然确保所有文件操作都按照主线程调用它们的顺序执行?

【问题讨论】:

  • 听起来您可能想查看 NSOperationQueue 或 GCD。这里是一些 Apple Docs 的链接:developer.apple.com/library/ios/documentation/General/…
  • 我的 5 分钟结束了,我无法编辑我的评论,但是,我还想说我认为你应该实现一个串行队列。
  • 是的,我知道 GCD,但不确定要搜索什么。我会看看......那么你认为在我的情况下全局串行队列是否有意义?
  • 当然。您说需要在后台线程上按一定顺序执行基本操作,这就是串行队列的用途。我个人喜欢 NSOperationQueue,因为它是一个高级 API,但最终取决于您。如果您确实选择使用 NSOperationQueue,请确保设置 maxConcurrentOperationCount = 1。您还可以为每个操作添加依赖项,例如,操作 B 依赖于操作 A 的完成,使用 addDependency: 方法。
  • @Max 虽然我更喜欢许多任务(网络队列、图像处理队列等)的操作队列,但对于通过串行队列进行基本同步,我通常建议使用 GCD。它简单高效,非常适合跨线程同步与特定对象的交互。在 并发编程指南Eliminating Lock-Based Code 部分中,他们使用 GCD 对此进行了说明。

标签: ios multithreading nsfilemanager


【解决方案1】:

您可以使用下面的代码来确保文件操作按照您想要的顺序完成。我还编写了一个示例函数,可以从任何线程调用它来执行文件操作。

    //this will create a queue 
    dispatch_queue_t _serialQueue = dispatch_queue_create("com.example.name", DISPATCH_QUEUE_SERIAL);

    //call methods on different threads, to be performed one after the other.
    dispatch_sync(_serialQueue, ^{ printf("1"); //call 1st method here 
     });
    printf("2");
    dispatch_sync(_serialQueue, ^{ printf("3"); //call second method here 
    });
    printf("4");

执行顺序为1234

下面是一个你可以调用的线程安全的 NSFileManager 方法示例。

-(void)threadSafeMethod{ //you can call this method from any thread and do file operations

NSFileManager *fileManager = [[NSFileManager alloc] init];

if ([fileManager fileExistsAtPath:sourceFile]) {

  NSError *error = nil;
  if (![fileManager copyItemAtPath:sourceFile
                            toPath:destFile
                             error:&error]) {
    // Deal with error
  }
}

}

如果您查看 NSFileManager 的类文档,概述部分包含以下警告:

共享 FileManager 对象的方法可以从 多个线程安全。但是,如果您使用委托来接收 有关移动、复制、删除和链接状态的通知 操作,您应该创建文件管理器的唯一实例 对象,将您的委托分配给该对象,并使用该文件管理器 开始您的操作。

无论如何,区别仅在于您如何启动 NSFileManager,一个使用 defaultManager,另一个分配 NSFileManager 的瞬间。

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2013-03-12
    • 2011-09-15
    • 1970-01-01
    • 2022-11-21
    • 1970-01-01
    • 2012-01-23
    • 2012-08-01
    • 2021-07-12
    • 2011-03-30
    相关资源
    最近更新 更多