如何知道是哪个FileSystemEvent从DispatchSource触发了setEventHandler?

问题描述 投票:0回答:2

当您设置 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()
swift dispatch
2个回答
4
投票

看起来保存了最后一个文件系统事件。

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.
}

0
投票

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:
        // ..
    }
}

这是一种在保持类型安全的同时显示事件的优雅方式。

© www.soinside.com 2019 - 2024. All rights reserved.