Согласно Apple documentation on Scripting Bridge performance, мы должны стремиться использовать пакетные операции на SBElementArrays
, так как звонки Apple происходят дорого.Scripting Bridge: Объединение SBElementArrays
... whenever possible you should always use one of the “batch operation” array methods instead of enumerating the array. These methods avoid the inefficiency of enumeration because they send a single Apple event rather than one Apple event per item in the array.
Я использую Scripting Bridge с приложением System Events, и я в состоянии получить пункты меню из меню успешно. Это намного быстрее, чем метод NSAppleScript, который я использовал ранее.
Что бы я хотел сделать, это объединить несколько элементов SBElementArrays, каждый из которых содержит пункты меню из разных меню. План состоит в том, чтобы затем запустить пакетную операцию один раз, а не делать это для каждого меню отдельно.
Мне кажется, что это не должно быть так сложно, хотя, очевидно, мои знания в этой области в лучшем случае ограничены. К сожалению, у меня серьезные ошибки.
Первая попытка
Если я пытаюсь создать пустой элемент SBElementArray, а затем цикл по пунктам меню, добавляя каждый набор пунктов меню, например, так:
SBElementArray* menuItemCombinedArray = [[SBElementArray alloc] init];
for (SystemEventsMenuBarItem* menu in menuBar.menus) {
menuItemCombinedArray = [[menuItemCombinedArray arrayByAddingObjectsFromArray:menu.menuItems] mutableCopy];
}
NSArray* menuItemNameArray = [menuItemCombinedArray arrayByApplyingSelector:@selector(name)];
Я получаю ошибку о том, что [SBElementArray init] should never be used
, что немного нечетно, поскольку SBElementArray является подклассом NSMutableArray.
Второй попытка
Далее я попробовал дилетантский путь, где я создал SBElementArray отдельно для первого меню, а затем петельного через остальное меню и добавил тот, SBObjects один в то время, как так:
SBElementArray* menus = menuBar.menus;
SystemEventsMenuBar* firstMenu = menus.firstObject;
SBElementArray* menuItemCombinedArray = firstMenu.menuItems;
[menus removeObjectAtIndex:0];
for (SystemEventsMenuBarItem* menu in menus) {
SBElementArray* tempMenuItemsArray = menu.menuItems;
for (int i = 0; i < tempMenuItemsArray.count; i++) {
[menuItemCombinedArray addObject:[tempMenuItemsArray objectAtIndex:i]];
}
}
NSArray* menuItemNameArray = [menuItemCombinedArray arrayByApplyingSelector:@selector(name)];
Но теперь я получаю другую ошибку: [SBElementArray addObject:]: can't add an object that already exists.'
Резюме
Из того, что я читал в поисках, это похоже на скриптовый мост в целом, и SBElementArray, в частности, выглядят неловко. Но Scripting Bridge для меня намного быстрее, чем NSAppleScript, гораздо ближе к тому, к чему я стремился. Я думаю, что если бы я смог добиться этой оптимизации, я был бы в отличной форме.
Заранее благодарим за любую помощь!
Большое спасибо за подробное объяснение. Я пытался сообщить календарю, чтобы показать определенный элемент, пока не выясню, что календарь uid и EKEventStore используют совпадение относительно самого календаря, но не для событий. По этой причине мне нужно будет найти событие по имени. Это, в свою очередь, требует много лет. Я просто отказываюсь от этого лома. –