【发布时间】:2018-06-28 23:34:38
【问题描述】:
我在 Xcode 9 中使用 Swift 制作了一个基本的 Mac OS X Cocoa 应用程序。该应用程序从用户那里收集源和目标,然后将数据从源传输到目标。通过将 rsync 脚本作为进程启动来完成数据传输:
let path = "/bin/bash"
let arguments = ["/path/to/backup.sh", sourcePath, destinationPath]
task = Process.launchedProcess(launchPath: path, arguments: arguments as! [String])
问题是,当传输运行时,应用程序会旋转彩虹轮,无法使用 GUI。这使得“取消”按钮或功能性进度条成为不可能。
传输完成后,应用程序会再次运行,并且任何测试输出(例如,打印语句、进度条)都会通过(而不是在备份运行时按预期进行)。
我认为线程可能有助于解决这个问题,所以我查看了这篇关于 Apple 线程的帖子:https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/CreatingThreads.html
但是,文章中的代码在 Xcode 中似乎没有正确的语法,所以我不确定如何继续使用线程。
我在死胡同,任何帮助将不胜感激!
运行应用程序后,在调试器中暂停,并在调试器控制台中输入“bt”,这是输出:
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
frame #0: 0x00007fff65fc120a libsystem_kernel.dylib`mach_msg_trap + 10
frame #1: 0x00007fff65fc0724 libsystem_kernel.dylib`mach_msg + 60
frame #2: 0x00007fff3dac4045 CoreFoundation`__CFRunLoopServiceMachPort + 341
frame #3: 0x00007fff3dac3397 CoreFoundation`__CFRunLoopRun + 1783
frame #4: 0x00007fff3dac2a07 CoreFoundation`CFRunLoopRunSpecific + 487
frame #5: 0x00007fff3cda0d96 HIToolbox`RunCurrentEventLoopInMode + 286
frame #6: 0x00007fff3cda0b06 HIToolbox`ReceiveNextEventCommon + 613
frame #7: 0x00007fff3cda0884 HIToolbox`_BlockUntilNextEventMatchingListInModeWithFilter + 64
frame #8: 0x00007fff3b053a73 AppKit`_DPSNextEvent + 2085
frame #9: 0x00007fff3b7e9e34 AppKit`-[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 3044
frame #10: 0x00007fff3b048885 AppKit`-[NSApplication run] + 764
frame #11: 0x00007fff3b017a72 AppKit`NSApplicationMain + 804
* frame #12: 0x000000010000a88d Mac Syncy`main at AppDelegate.swift:12
frame #13: 0x00007fff65e7a015 libdyld.dylib`start + 1
frame #14: 0x00007fff65e7a015 libdyld.dylib`start + 1
【问题讨论】:
-
您的程序中是否还有引用
task的代码?启动进程不应自行挂起应用程序。 -
你在哪里运行任务?您的代码仅显示了您如何创建实例(顺便说一句。通过已弃用的 API;您应该使用
init()),而不是它是如何开始的。 -
@duskwuff 不,没有其他对
task变量的引用。我曾尝试使用task?.waitUntilExit()启动,但效果相同。我还尝试使用while task?.isRunning进行一些测试,但我们对此无能为力。就像程序看不到task正在运行一样。 -
程序卡住的时候,在调试器中暂停一下,看看主线程的栈。这将向您显示卡在哪里,这通常可以帮助您找出卡住的原因。
-
@AndreasOetjen
Process.launchedProcess部分正在启动进程。我不完全确定它是如何工作的,我在网上找到了它。如何使用init()启动进程?
标签: swift multithreading cocoa xcode9 freeze