Как выполнить метод NSFileCoordinator.coordinate (), не вызывая блокировку потока в моем коде? - PullRequest
0 голосов
/ 28 сентября 2018

Я пытаюсь имитировать этот код, полученный из примера проекта Apple ShapeEdit.Разница в том, что я использую две очереди операций - одну для инкапсуляции кода NSFileCoordinator.coordinate (), а другую - в качестве аргумента для метода координат.Я установил maxConcurrentOperationCount для обеих этих очередей равным 1, потому что я выполняю файловые операции, которые должны выполняться последовательно.Если iCloud переименовывает файл и сообщает об этом MetadataQuery, я должен обработать переименование файла после создания файла.Я пытаюсь выяснить, как сделать это, не вызывая блокировку потока, когда он не завершает выполнение и не позволяет выполнять все другие потоки.Вот почему я использую две очереди операций.

Я также хотел бы знать, где должна быть область действия переменной файлового менеджера, чтобы не вызывать блокировку потока, когда операция не освобождается, потому чтоу него есть ссылка на объект извне через захват.Я помню документацию о том, чтобы ничего не делать внутри замыкания координат, кроме процесса файлаЯвляется ли хорошей идеей создать переменную для объекта файлового менеджера в замыкании координат?

Мне не нужно показывать код, так как я все объяснил выше, но я все равно показываю код.

Я открыт для любых предложений.Я совершенно не уверен в том, что я делаю.Мы будем благодарны за любую помощь.

Следующие сегменты кода - это отредактированный код ShapeEdit:

fileprivate let coordinationQueue: OperationQueue = {
    let coordinationQueue = OperationQueue()

    coordinationQueue.name = "com.example.apple-samplecode.ShapeEdit.documentbrowser.coordinationQueue"

    return coordinationQueue
}()


coordinationQueue.addOperation {

    let readIntent = NSFileAccessIntent.readingIntent(with: templateURL, options: [])

    let writeIntent = NSFileAccessIntent.writingIntent(with: target, options: .forReplacing)

    NSFileCoordinator().coordinate(with: [readIntent, writeIntent], queue: self.coordinationQueue) { error in
        if error != nil {
            return
        }

        do {
            try fileManager.copyItem(at: readIntent.url, to: writeIntent.url)

            try (writeIntent.url as NSURL).setResourceValue(true, forKey: URLResourceKey.hasHiddenExtensionKey)

            OperationQueue.main.addOperation {
                self.openDocumentAtURL(writeIntent.url)
            }
        }
        catch {
            fatalError("Unexpected error during trivial file operations: \(error)")
        }
    }
}

Следующие сегменты кода - мой код:

internal let operationQueue: OperationQueue = {

    let operationQueue = OperationQueue()

    operationQueue.name = "us.gnolaum.IPv4Calculator.operationQueue"

    operationQueue.maxConcurrentOperationCount = 1

    return operationQueue

}()

internal let coordinationQueue: OperationQueue = {

    let coordinationQueue = OperationQueue()

    coordinationQueue.name = "us.gnolaum.IPv4Calculator.coordinationQueue"

    coordinationQueue.maxConcurrentOperationCount = 1

    return coordinationQueue

}()


operationQueue.addOperation {

    let readIntent = NSFileAccessIntent.readingIntent(with: item.url, options: [])

    let destinationURL = self.localDocumentsURL.appendingPathComponent(item.url.lastPathComponent)

    let writeIntent = NSFileAccessIntent.writingIntent(with: destinationURL, options: .forReplacing)

    NSFileCoordinator().coordinate(with: [readIntent, writeIntent], queue: coordinationQueue) { error in
        if error != nil {
            return
        }

        do {

            try self.defaultFileManager.copyItem(at: readIntent.url, to: writeIntent.url)

            print("\(readIntent.url.lastPathComponent) copied to iCloud")

        } catch {

            print(error.localizedDescription)

        }

    }

}
...