使用 NSPredicate 和 FourCharCodes 编写 Bridge 脚本并过滤 SBElementArrays
我是第一次尝试 Scripting Bridge,但在根据包含 FourCharCode 枚举常量作为标准的 NSPredicate 过滤 SBElementArray
时遇到了问题。
我编写了一个简单的程序来识别用户 iTunes 库中的“库”源,方法是使用 -filteredArrayUsingPredicate:
来过滤所有 iTunes 源的 SBElementArray
。我期望返回一个 SBElementArray
,在评估时,它会生成一个包含一个元素的数组,即库源。相反,当我对返回的 SBElementArray 调用 -get
时,我得到一个空数组。
令人困惑的是,如果更改顺序,而是对所有源的 SBElementArray
调用 -get
来获取具体的 NSArray
,然后调用 - FilteredArrayUsingPredicate:在这个具有与之前相同的谓词的数组上,我确实得到了所需的结果。然而,我不认为这是必要的,并且我已经使用其他 NSPredicates 成功过滤了
SBElementArray
(例如 @"name=='Library'"
工作正常)。
代码片段如下。 iTunesESrcLibrary
是在 Scripting Bridge 生成的头文件中定义的 FourCharCode 常量。 (iTunesESrcLibrary = 'kLib'
)。我正在运行 10.6.5。
iTunesApplication* iTunes = [[SBApplication alloc] initWithBundleIdentifier:@"com.apple.iTunes"];
NSPredicate* libraryPredicate = [NSPredicate predicateWithFormat:@"kind == %u", iTunesESrcLibrary];
SBElementArray* allSources_Attempt1 = [iTunes sources];
SBElementArray* allLibrarySources_Attempt1 = (SBElementArray*)[allSources_Attempt1 filteredArrayUsingPredicate:libraryPredicate];
NSLog(@"Attempt 1: %@", allLibrarySources_Attempt1);
NSLog(@"Attempt 1 (evaluated): %@", [allLibrarySources_Attempt1 get]);
NSArray* allSources_Attempt2 = [[iTunes sources] get];
NSArray* allLibrarySources_Attempt2 = [allSources_Attempt2 filteredArrayUsingPredicate:libraryPredicate];
NSLog(@"Attempt 2: %@", allLibrarySources_Attempt2);
我得到的输出如下:
Attempt 1: <SBElementArray @0x3091010: ITunesSource whose 'cmpd'{ 'relo':'= ', 'obj1':'obj '{ 'want':'prop', 'from':'exmn'($$), 'form':'prop', 'seld':'pKnd' }, 'obj2':1800169826 } of application "iTunes" (88827)>
Attempt 1 (evaluated): (
)
Attempt 2: (
"<ITunesSource @0x3091f10: ITunesSource id 65 of application \"iTunes\" (88827)>"
)
I'm experimenting with Scripting Bridge for the the first time, but have run into an issue with filtering a SBElementArray
according to a NSPredicate containing a FourCharCode enum constant as a criterion.
I wrote a trivial program to identify the "library" source in a user's iTunes library, by using -filteredArrayUsingPredicate:
to filter the SBElementArray
of all iTunes sources. I was expecting to get back an SBElementArray
that, when evaluated, would produce an array of one element, namely the library source. Instead, when I call -get
on the returned SBElementArray
, I get back an empty array.
Perplexingly, if change the order and instead call -get
on the SBElementArray
of all sources to get a concrete NSArray
, and call -filteredArrayUsingPredicate:
on this array with the same predicate as before, I do get the desired result. I don't believe this is supposed to be necessary however, and I've had success filtering a SBElementArray
using other NSPredicates (e.g. @"name=='Library'"
works fine).
The code snippet is below. iTunesESrcLibrary
is a FourCharCode constant defined in the header file generated by Scripting Bridge. (iTunesESrcLibrary = 'kLib'
). I'm running 10.6.5.
iTunesApplication* iTunes = [[SBApplication alloc] initWithBundleIdentifier:@"com.apple.iTunes"];
NSPredicate* libraryPredicate = [NSPredicate predicateWithFormat:@"kind == %u", iTunesESrcLibrary];
SBElementArray* allSources_Attempt1 = [iTunes sources];
SBElementArray* allLibrarySources_Attempt1 = (SBElementArray*)[allSources_Attempt1 filteredArrayUsingPredicate:libraryPredicate];
NSLog(@"Attempt 1: %@", allLibrarySources_Attempt1);
NSLog(@"Attempt 1 (evaluated): %@", [allLibrarySources_Attempt1 get]);
NSArray* allSources_Attempt2 = [[iTunes sources] get];
NSArray* allLibrarySources_Attempt2 = [allSources_Attempt2 filteredArrayUsingPredicate:libraryPredicate];
NSLog(@"Attempt 2: %@", allLibrarySources_Attempt2);
The output I get is the following:
Attempt 1: <SBElementArray @0x3091010: ITunesSource whose 'cmpd'{ 'relo':'= ', 'obj1':'obj '{ 'want':'prop', 'from':'exmn'($), 'form':'prop', 'seld':'pKnd' }, 'obj2':1800169826 } of application "iTunes" (88827)>
Attempt 1 (evaluated): (
)
Attempt 2: (
"<ITunesSource @0x3091f10: ITunesSource id 65 of application \"iTunes\" (88827)>"
)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我想我已经明白了。看来您不能简单地在打算用于过滤
SBElementArray
的NSPredicate
中直接使用 FourCharCode 的整数值。而不是
一次偶然的机会,我发现您需要使用:
:使用第二种形式,我可以按预期过滤
SBElementArray
源列表。但是,这个新谓词不能用于过滤NSArray
,即使该数组只是SBElementArray
的计算形式!这里,你必须切换回%u
版本。咆哮:
坦率地说,这很糟糕,而且这似乎是 Scripting Bridge 应该处理的事情,所以我不必这样做;我不必知道 NSAppleEventDescriptor 是什么。虽然并非所有适用于
NSArray
的谓词都适用于SBElementArray
,这是合理的,但反之则不应该如此,而且这样会造成不必要的混乱。I think I've figured it out. It seems you can't simply use a FourCharCode's integer value directly in a
NSPredicate
that you intend to use to filter anSBElementArray
.By chance, I found that instead of:
you need to use:
Using this second form, I can filter the
SBElementArray
sources list as expected. However, this new predicate can't be used to filter theNSArray
, even though this array is just the evaluated form of theSBElementArray
! Here, you have to switch back to the%u
version.Rant:
Frankly this sucks, and it seems the sort of thing Scripting Bridge should deal with so I don't have to; I shouldn't have to know what an
NSAppleEventDescriptor
is. And while it's reasonable that not all predicates that work withNSArray
should work withSBElementArray
, the converse should not be the case and it's unnecessarily confusing that it is.