当您设置 eventMask 以捕获所有 FileSystemEvents 时,如下面的代码所示。您如何能够检索哪个事件触发了该方法?
self.source = DispatchSource.makeFileSystemObjectSource(fileDescriptor: descriptor, eventMask: .all, queue: DispatchQueue.main)
guard let source = self.source else {
return
}
source.setCancelHandler {
if let descriptor = self.descriptor {
close(descriptor)
self.descriptor = nil
}
}
source.setEventHandler { [weak self] in
// How to know which FileSystemEvent triggered this method?
}
source.resume()
看起来源保存了最后一个文件系统事件。
source.setEventHandler { [weak self] in
print(source.data)
}
我还创建了一个小帮手:
extension DispatchSourceFileSystemObject {
var dataStrings: [String] {
var s = [String]()
if data.contains(.all) { s.append("all") }
if data.contains(.attrib) { s.append("attrib") }
if data.contains(.delete) { s.append("delete") }
if data.contains(.extend) { s.append("extend") }
if data.contains(.funlock) { s.append("funlock") }
if data.contains(.link) { s.append("link") }
if data.contains(.rename) { s.append("rename") }
if data.contains(.revoke) { s.append("revoke") }
if data.contains(.write) { s.append("write") }
return s
}
}
现在如果您将代码更改为:
source.setEventHandler { [weak self] in
print(source.dataStrings) // Will output all flags in readable format.
}
DispatchSource.data
的类型为 DispatchSource.FileSystemEvent
并且符合 OptionSet
,这意味着一个事件可以容纳多个事件选项。
我正在寻找一种简单、可重用的方式来打印和迭代事件,所以我编写了这些扩展:
extension DispatchSource.FileSystemEvent: CustomStringConvertible {
public var description: String {
switch self.rawValue {
case 1:
return "delete"
case 2:
return "write"
case 4:
return "extend"
case 8:
return "attrib"
case 16:
return "link"
case 32:
return "rename(move)"
case 64:
return "revoke"
case 128:
return "funlock"
case 256:
return "all"
default:
return "#\(self.rawValue) \(self.options) "
}
}
/// Returns all included option elements as an array of single events
public var options: [DispatchSource.FileSystemEvent] {
var array: [DispatchSource.FileSystemEvent] = []
if self.contains(.delete) { array.append(.delete) }
if self.contains(.write) { array.append(.write) }
if self.contains(.extend) { array.append(.extend) }
if self.contains(.attrib) { array.append(.attrib) }
if self.contains(.funlock) { array.append(.funlock) }
if self.contains(.rename) { array.append(.rename) }
if self.contains(.revoke) { array.append(.revoke) }
if self.contains(.link) { array.append(.link) }
if self.contains(.all) { array.append(.all) }
return array
}
}
用它来调试:
print("\(event.description)") // e.g. "#6 [write, extend]"
并迭代事件:
for event in source.data.options {
switch event {
case .extend:
// ...
case .delete, .rename:
// ...
default:
// ..
}
}
这是一种在保持类型安全的同时显示事件的优雅方式。