У меня похожая проблема на новом Mac Pro, но еще хуже. В macOS 10.15.3 Catalina я не могу получить данные system_profiler для «SPAudioDataType». Могут быть вызваны другие процессы, такие как curl и т. д., но проблема с system_profiler.
Самая забавная вещь в моей проблеме заключалась в том, что это произошло только через 10 минут после нового перезапуска. В первые 10 минут все работало, с использованием обработчиков или без них и даже с кодом «getApplications» из ответа выше.
И да, конечно, я запускаю его в основном потоке, но нет никакой разницы, работает он в основном потоке или нет.
Я много экспериментировал, чтобы посмотреть, что является источником такого поведения. Я обнаружил, что мои программы зависают при чтении данных командой
let data = taskOutput.fileHandleForReading.readDataOfLength(1024)
в случае наличия данных об ошибках и наоборот программа зависает при чтении сообщений об ошибках командой
let data = taskError.fileHandleForReading.readDataOfLength(1024)
в случае, если имеются нормальные данные (но нет данных об ошибках).
Программа даже зависает, если я пытаюсь получить тот объем данных, который доступен на данный момент:
let c = taskError.fileHandleForReading.availableData.count
Независимо от того, что я тестирую в первую очередь, программа зависает, если нет доступных данных.
Поэтому я полностью переписал свою функцию для использования асинхронных обработчиков:
@discardableResult func launchprogram (_ launchpath: String, _ arguments: [String]) -> (result: String, error: Int)
{
var out: String = "" // Output
var err: String = "" // Error Messages
var fin: Bool = false // If the process exits normally
let pro: Process = Process()
pro.arguments = arguments
pro.launchPath = launchpath
pro.standardOutput = Pipe()
pro.standardError = Pipe()
let proOut: Pipe = pro.standardOutput as! Pipe
let proIn: Pipe = pro.standardError as! Pipe
proOut.fileHandleForReading.readabilityHandler =
{
pipe in
if let line = String(data: pipe.availableData, encoding: String.Encoding.utf8)
{
if line.count > 0 // Neuen Ausgabe-Text hinzufügen
{
out += line
}
}
}
proIn.fileHandleForReading.readabilityHandler =
{
pipe in
if let line = String(data: pipe.availableData, encoding: String.Encoding.utf8)
{
if line.count > 0 // Neuen Fehler-Text hinzufügen
{
err += line
}
}
}
pro.terminationHandler =
{
(process) in
fin = not(process.isRunning)
}
pro.launch()
pro.waitUntilExit()
if err == ""
{
if fin
{
return (out, 0)
}
else
{
return (out, -1)
}
}
else if out == ""
{
let message: String = "Error while executing:" + char(13) + char(13)
return (message + err, -2)
}
else
{
let message: String = char(13) + char(13) + "Error while executing:" + char(13) + char(13)
return (out + message + err, -3)
}
}
Фундаментальное отличие этой функции от функции «getApplications» из предыдущего поста заключается в том, что я использую «обработчик» для управления потоками вывода и сообщений об ошибках. Это всегда работает. Цель развертывания может быть 10.9 или выше. Я не тестировал его с 10.8 и ранее. Итак, моя проблема заключалась в том, что в Catalina при некоторых обстоятельствах больше невозможно получать информацию в «нормальном» синхронном порядке, а только асинхронно с использованием обработчиков. Если я прерву выполнение, я всегда буду в чем-то вроде «libsystem_kernel.dylibread" withe the calling function "Foundation
_NSReadFromFileDescriptorWithProgress». Я был бы рад узнать, является ли это проблемой Catalina (с новым Mac Pro) или фундаментальным изменением того, что Apple хочет, чтобы мы использовали.
person
j.s.com
schedule
12.03.2020