Uwaga: problem delay
został rozwiązany w systemie OS X 10.11 El Capitan.
Od czasu aktualizacji do Yosemite, Applescripts, które używają opóźnień przestały działać. Jak mogę to naprawić?
Oto najprostszy na świecie skrypt jabłkowy dla prostego przykładu:
set volume output volume 0
delay 5
set volume output volume 20
delay 5
set volume output volume 0
delay 5
set volume output volume 20
delay 5
set volume output volume 0
delay 5
set volume output volume 20
delay 5
set volume output volume 0
Powinno to zająć 30 sekund. Jeśli uruchomię go w Script Editor (wcześniej Applescript Editor), wykonanie go zajmuje 30 sekund. Ale jeśli zapiszę ten skrypt jako aplikację, po uruchomieniu aplikacji opóźnienia zostaną zignorowane, a aplikacja zajmie ułamek sekundy.
Jak zmusić skrypt Apple do opóźnienia przez określony czas przed przejściem do następnego kroku? Czy to usterka Yosemite? Czy istnieje niezawodne obejście?
yosemite
applescript
2oh1
źródło
źródło
Odpowiedzi:
Uwaga: problem
delay
został rozwiązany w systemie OS X 10.11 El Capitan.@ 2oh1, masz właściwą podstawową ideę w swojej odpowiedzi, ale oto pełna i poprawna odpowiedź:
Jedynym rozsądnym sposobem obejścia tego problemu jest wywołanie „opóźnienia” w pętli, która zapewnia upłynięcie pożądanego czasu trwania przed kontynuowaniem. Najlepszym sposobem na to jest zastąpienie „opóźnienia” za pomocą niestandardowego modułu obsługi:
Umożliwia to pozostawienie pozostałej części skryptu bez zmian i można normalnie używać „opóźnienia”, np.
[UWAGA: Zwykle niestandardowy moduł obsługi używałby opcji „kontynuuj opóźnienie”, aby wywołać wbudowane „opóźnienie”, ale odkryłem, że chociaż działa to w edytorze skryptów, zwraca błąd, gdy jest używany w aplecie („Can” t kontynuuj opóźnienie. (-1708) ”). Obejrzałem ten problem, mówiąc bezpośrednio AppleScript, aby obsługiwał polecenie opóźnienia zamiast używać „kontynuuj”, aby się tam dostać.]
Problem polega na tym
delay
, że przetwarza dane wprowadzone przez użytkownika podczas wstrzymywania skryptu, dzięki czemu nadal możesz klikać menu lub okna wyświetlane przez aplet, i występuje błąd (naprawiony w 10.11), w wyniku którego dane wejściowe użytkownikadelay
nie czekają na pełny czas trwania przed wznowieniem wykonywania skryptu . Jeśli nie wchodzisz w interakcję z apletem,delay
działa poprawnie.źródło
Walcząc z tym samym problemem, natknąłem się na odpowiedź na niezbyt związane pytanie i postanowiłem spróbować, a wydaje mi się, że to działa.
Wystarczy wymienić
delay 5
siędo shell script "/bin/sleep 5"
i uzyskać ten sam rezultat.źródło
/bin/sleep
czeka na czas snu i nie powraca, dopóki się nie zakończy. Natomiast wbudowanedelay
polecenie AppleScript obsługuje zdarzenia wejściowe użytkownika, gdy skrypt jest wstrzymany. (W tym tkwi błąd: jeśli wprowadzono klawiaturę użytkownika,delay
kontynuuje wykonywanie skryptu przed upływem czasu opóźnienia).Nie twierdzę, że to najlepsze rozwiązanie, ale wydaje się, że rozwiązało mój problem. Zamiast korzystać z prostego opóźnienia, które jest ignorowane z powodów, których nie rozumiem, przestawiłem się na uzyskiwanie czasu i zapętlanie się do nowego czasu (nadal używa opóźnienia, ale nie ma znaczenia, czy ignoruje opóźnienie, ponieważ skrypt nie jest kontynuowany, dopóki nie zostanie osiągnięty czas).
Nadal nie mogę się doczekać, aby wiedzieć, dlaczego opóźnienie jest ignorowane (lub gwałtownie przyspieszone?! ??), ale to sprawia, że praca jest wykonywana, niezgrabna jak na razie.
źródło
delay
będzie kontynuowane, dopóki coś nie obsłuży zdarzeń i usunie je z kolejki.Znalazłem obejście w niemieckim poście na forum . Dodaj następujące wiersze na początku skryptu:
źródło
delay
przetwarza dane wejściowe użytkownika, gdy skrypt jest wstrzymany, dzięki czemu można na przykład wchodzić w interakcje z menu i oknami.carzyj miał odpowiedź, którą uważam za najlepszą, ale w połączeniu z metodą Chrisa Pagea otrzymujesz:
Możesz skomentować „opóźnienie” do „opóźnienie zakończenia”, aby powrócić do pierwotnego opóźnienia.
źródło
jest to modyfikacja rozwiązania @ chris-page
Wydaje się, że jest to równowaga między reaktywnością a dokładnym rejestrowaniem opóźnienia.
Ale zamiast mówić Applescriptowi, aby opóźniał cały czas trwania, po prostu mówimy mu, żeby opóźniał o ułamek czasu trwania. jeśli okres jest krótszy niż pozwala jabłko (1/60 sekundy), ustawmy go właśnie na tę różnicę. Że możemy zachować pewien czas reakcji, a jednocześnie zachować dokładność. podejrzewa się, że czasami opóźnienie nie działa, więc powtarzanie pętli while spowoduje zablokowanie wątku, ale w scenariuszach sukcesu chcemy, aby delta opóźnienia była krótka, aby proces mógł być nadal przerywany
źródło
delay
na jak największe opóźnienie, zanim będzie można kontynuować wykonywanie.delay endTime - (current date)
zamiastdelay duration
, co zapewnia, że jeślidelay
nie zostanie przerwany, skrypt nie zatrzyma się dłużej niż pierwotnie żądany czas, który mógł być tym, co próbujesz adres z tą odpowiedzią.Podsumowując, uważam, że Chris ma na myśli to:
źródło