#script object を使用したリスト処理
AppleScript は、リスト処理がとにかく遅いので有名です。
たとえば、以下のスクリプトは
1〜10,000をループさせて、一つずつ文字列に変換しつつリストに代入してゆくのですが、
とにかく実行してみてください。
**サンプルコード1**
use scripting additions
use framework "Foundation"
set eDate to current application's NSDate's timeIntervalSinceReferenceDate()
set a to {}
repeat with i from 1 to 10000
set end of a to i as string
end repeat
display alert ((((current application's NSDate's timeIntervalSinceReferenceDate()) - eDate) & "秒かかりました") as string)
私のMacBook Pro(os10.14.6/2.2GHz Intel Core i7)では
こうなりました。
いやいや…
こんなのに約1.4秒は遅いでしょ。
ということで、
リストを script object にしてみます。
**サンプルコード2**
use scripting additions
use framework "Foundation"
set eDate to current application's NSDate's timeIntervalSinceReferenceDate()
script a
property contents : {}
end script
set contents of a to {}
repeat with i from 1 to 10000
set end of contents of a to i as string
end repeat
display alert ((((current application's NSDate's timeIntervalSinceReferenceDate()) - eDate) & "秒かかりました") as string)
単にリストを定義するのではなく、
script object の property を使用してリスト定義をすると、
なぜか高速化するのです。
これについては以下のサイトを参考にさせて頂きました。
#では早速 Adobe アプリケーションに使ってみよう
こんなに速くなるのなら、と
Illustrator やら、 InDesign やら
大量にリストを使用する script に使ってみます。
以下は、Illustrator ドキュメント上の
全ての text frame をリストに代入しようとしています。
**サンプルコード3**
script allText
property contents : {}
end script
tell application "Adobe Illustrator"
tell document 1
set contents of allText to text frames
end tell
end tell
というのは、
Adobe Illustrator は、
「contents」という property を内部で使っているからです。
なんという意地悪!
#じゃ、結局使えないの?
そんなことはないです。
**サンプルコード4**
script allText
property record : {}
end script
tell application "Adobe Illustrator"
tell document 1
set record of allText to text frames
end tell
end tell
「contents」を「record」に変えるだけで、
使用できるようになります。
Adobe Indesign も同様に、
**サンプルコード5**
script allPageItems
property record : {}
end script
tell application "Adobe InDesign CC 2019"
tell document 1
set record of allPageItems to all page items
end tell
end tell
なぜ「record」が使えるのか、
私にはよくわかりません。
わかりませんが、
これであなたの作った script も確実に高速化します。
#最後に注意点
リストの高速化で、
一点だけ注意して欲しいこと。
それは、script obejct に対して
「count」が使えなくなることです。
**サンプルコード6**
script allPageItems
property record : {}
end script
tell application "Adobe InDesign CC 2019"
tell document 1
set record of allPageItems to all page items
end tell
end tell
repeat with i from 1 to count of record of allPageItems
get item i of record of allPageItems
end repeat
**サンプルコード7**
script allPageItems
property record : {}
end script
tell application "Adobe InDesign CC 2019"
tell document 1
set record of allPageItems to all page items
end tell
end tell
repeat with i from 1 to length of record of allPageItems
get item i of record of allPageItems
end repeat
よしよし。
では皆様、今後ともよろしくお願いいたします。