swift - 处理来自 Swift 的 FSEventStreamRef API 中的选项

标签 swift macos

我正在尝试观察一个文件夹,以查看 Mac OS 上该文件夹中是否创建/修改/删除了文件等。我已经读到我想使用的是文件系统事件,但我无法让我的代码工作。

我尝试阅读 docs at apple并阅读了 stackoverflow 上的不同帖子,但我发现似乎没有任何内容可以在 swift 4 和 xcode 10 上运行。

    init(path: String) {
        let allocator: CFAllocator? = kCFAllocatorDefault

        // Create FSEventStream and return valid FSEventStreamRef
        // Alias FSEventStreamCallback - CFunction

        typealias FSEventStreamCallback = @convention(c) (ConstFSEventStreamRef, UnsafeMutableRawPointer?, Int, UnsafeMutableRawPointer, UnsafePointer<FSEventStreamEventFlags>, UnsafePointer<FSEventStreamEventId>) -> Void


        let callback: FSEventStreamCallback = {
            (streamRef, clientCallBackInfo, numEvents, eventPaths, eventFlags, eventIds) -> Void in
            print ("changed")
            // handle file event
        }

        let context: UnsafeMutablePointer<FSEventStreamContext>? = nil
        let pathsToWatch: CFArray = [NSHomeDirectory() + path] as CFArray
        let sinceWhen: FSEventStreamEventId = UInt64(kFSEventStreamEventIdSinceNow)
        let latency: CFTimeInterval = 1.0
        let flags: FSEventStreamCreateFlags = UInt32(kFSEventStreamCreateFlagNone)
        let eventStream = FSEventStreamCreate(
            allocator,
            callback,
            context,
            pathsToWatch,
            sinceWhen,
            latency,
            flags
        )

        FSEventStreamScheduleWithRunLoop(eventStream, CFRunLoopGetCurrent(), CFRunLoopMode.defaultMode as! CFString)
        FSEventStreamStart(eventStream!)
    }

我要么收到错误

Value of optional type 'FSEventStreamRef?' (aka 'Optional<OpaquePointer>') must be unwrapped to a value of type 'FSEventStreamRef' (aka 'OpaquePointer')

当我尝试构建或

Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)

在运行时如果我添加一个“!”到“事件流”

我需要更改什么才能让它运行?

最佳答案

eventStream 必须展开 - 最好使用可选绑定(bind),例如

guard let eventStream = FSEventStreamCreate(...) else {
     // handle error ...
}

但真正导致程序崩溃的是强制转换

FSEventStreamScheduleWithRunLoop(..., CFRunLoopMode.defaultMode as! CFString)

CFRunLoopMode 不是 CFString,因此强制 as! CFString 失败。它是一个struct CFRunLoopMode: RawRepresentable,底层的CFString是通过rawValue属性获得的:

FSEventStreamScheduleWithRunLoop(..., CFRunLoopMode.defaultMode.rawValue)

备注: typealias FSEventStreamCallback 已在核心服务框架中定义,无需在您的类中重复定义。

关于swift - 处理来自 Swift 的 FSEventStreamRef API 中的选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54752349/

相关文章:

swift - 如何获得随机枚举字符串?

ios - scrollView.scrollRectToVisible() 只能在模拟器中使用?

c++ - 如何在 OSX 中获取程序的最大内存使用量

c# - 将 WinForms 应用程序移植到 Mac OS

Python 'Logger' 模块双重记录

cocoa-touch - 无法调用 UITableViewDelegate tableView(tableView, didSelectRowAtIndexPath : indexPath) from UITableView subclass

ios - 为什么我的多 channel 映射不能正常工作?

swift - 将远程帧缓冲区流式传输到 NSView

python - 在 Homebrew 程序中使用系统Python

macos - 如何运行 julia-lang 文件 - Mac OS X