Ich schreibe eine Anwendung, die einen Subprozess startet, der einen einfachen Webserver ausführt. Ich benutze NSTask und kommuniziere damit mit Pipes, und alles scheint mehr oder weniger gut zu sein. Wenn jedoch mein Programm abstürzt, bleibt der Subprozess bestehen und beim nächsten Start der App gibt es einen Konflikt zwischen dem alten und dem neuen Subprozess. Gibt es eine Möglichkeit sicherzustellen, dass Subprozesse sterben, wenn die Owning App stirbt?
Keins der oben genannten funktioniert ... Nicht einmal launchd
in allem ist es crappily-dokumentiert-Komplexität hat eine Möglichkeit, dieses häufige Szenario zu behandeln. Ich weiß nicht, warum Apple nicht nur einen "Mutterschiff-genehmigten" Weg zum Ausführen von Hintergrundprozessen macht, aber was auch immer ... meine Lösung ist ...
Starten Sie ein Shell-Skript über NSTask und übergeben Sie alle Variablen, die Sie benötigen. Übergeben Sie auch Ihren übergeordneten Prozess 'PID über int masterPID = [[NSProcessInfo processInfo] processIdentifier];
usw. Lesen Sie diese in Ihrem Skript über $ 1, $ 2, etc.
Starten Sie ihrerseits Ihre Subprozesse von innerhalb des Skripts ..
Überwachen Sie sowohl den Unterprozess UND als auch den übergeordneten Prozess innerhalb des Skripts.
Dies dient einem doppelten Zweck .. es ermöglicht Ihnen, "die Kinder im Auge zu behalten ..", und im traurigen Fall des Elternfalls (oder schrecklichen Autounfalls) - töten die Zombie-Waisen . Dann ziehst du den Auslöser auf dich selbst ( du bist das Shell-Skript ) und deine Prozesstabelle wird sauber sein. als ob du nie existiert hättest . Keine blockierten Ports, keine Konflikte beim Relaunch, keine App-Store-Ablehnungen. Lemme wissen, ob das hilft!
Update: Ich habe eine Xcode-Vorlage / einen Daemon / ein Projekt / was auch immer gemacht. Schau es dir an ... mralexgray / Infanticide
Ihr Anwendungsdelegierter kann das
implementieren %Vor%Nachricht, und beenden Sie die NSTask dort. Es ist jedoch nicht garantiert, dass dieser Delegat während eines Absturzes aufgerufen wird.
Zwei weitere Schritte, die Sie ausführen können:
UPDATE: Jetzt, wo ich das richtig überprüfe, funktioniert es nicht. Der Versuch, die Prozessgruppe festzulegen, schlägt mit diesem Fehler fehl;
EPERM "Die effektive Benutzer-ID des angeforderten Prozesses unterscheidet sich von der des aufrufenden Prozesses und der Prozess ist kein Nachkomme des aufrufenden Prozesses."
Es gibt einen kürzeren Thread zu diesem Thema, aber keine einfache Lösung, soweit ich das beurteilen kann
Ich habe einen Vorschlag von Robert Pointon auf Cocoadev in meiner App versucht. Ich bin aber noch nicht dazu gekommen es zu testen.
Die Idee besteht darin, die Prozessgruppe der Aufgabe so zu setzen, dass sie mit der des Prozesses identisch ist, der die Aufgabe startet (Hinweis: Der unten stehende Code wird grundsätzlich aus dem obigen Thread entfernt).
%Vor%