如何指定 NSDictionary 的keysOfEntriesPassingTest 所需的块对象/谓词?

发布于 2024-09-05 11:44:17 字数 1040 浏览 6 评论 0原文

出于学习(尚不实用)的目的,我想在 NSDictionary 上使用以下方法,通过我定义的测试返回一组具有值的键。不幸的是不知道如何指定谓词。

NSDictionary keysOfEntriesPassingTest:
- (NSSet *)keysOfEntriesPassingTest:(BOOL (^)(id key, id obj, BOOL *stop))predicate

比方说,我所有的值都是 NSURL,我想取回端口 8080 上的所有 URL。这是我的编码尝试 - 尽管对我来说这并没有什么意义正确:

NSSet * mySet = [myDict keysOfEntriesPassingTest:^(id key, id obj, BOOL *stop) {
                 if( [[obj port] isEqual: [NSNumber numberWithInt: 8080]]) {
                     return key;
                 }]

那是因为我收到以下编译器错误:

初始化“void (^)(struct objc_object *, struct objc_object *, BOOL *)”时不兼容的块指针类型,应为“BOOL (^)(struct objc_object *, struct objc_object *, BOOL *)”

我缺少什么?我很感激一些文档的指针,这些文档更详细地介绍了谓词应该是的“块对象”。
谢谢!


这是有效的代码:

NSSet *mySet = [myDict keysOfEntriesPassingTest:^(id key, id obj, BOOL *stop)
{
  if ([[obj port] isEqual:[NSNumber numberWithInt: 8080]])
     return YES;
   else
     return NO;
}];

For learning (not practical -- yet) purposes, I'd like to use the following method on an NSDictionary to give me back a set of keys that have values using a test I've defined. Unfortunately have no idea how to specify the predicate.

NSDictionary keysOfEntriesPassingTest:
- (NSSet *)keysOfEntriesPassingTest:(BOOL (^)(id key, id obj, BOOL *stop))predicate

Let's say for example all my values are NSURLs, and I'd like to get back all the URLs that are on port 8080. Here's my stab at coding that -- though it doesn't really make sense to me that it'd be correct:

NSSet * mySet = [myDict keysOfEntriesPassingTest:^(id key, id obj, BOOL *stop) {
                 if( [[obj port] isEqual: [NSNumber numberWithInt: 8080]]) {
                     return key;
                 }]

And that's because I get back the following compiler error:

incompatible block pointer types initializing 'void (^)(struct objc_object *, struct objc_object *, BOOL *)', expected 'BOOL (^)(struct objc_object *, struct objc_object *, BOOL *)'

What am I missing? I'd appreciate a pointer at some docs that go into more detail about the "Block object" that the predicate is supposed to be.

Thanks!


And this is the code that works:

NSSet *mySet = [myDict keysOfEntriesPassingTest:^(id key, id obj, BOOL *stop)
{
  if ([[obj port] isEqual:[NSNumber numberWithInt: 8080]])
     return YES;
   else
     return NO;
}];

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

携余温的黄昏 2024-09-12 11:44:17

对巴里的答案进行一点扩展……

块就像一个函数指针,但有一个关键区别。块将从中包含的返回语句推断返回类型,它将给出一条错误消息,如您所说的那样(LLVM编译器的错误应该更合理一些)。

当您写道:

NSSet * mySet = [myDict keysOfEntriesPassingTest:^(id key, id obj, BOOL *stop) {
                 if( [[obj port] isEqual: [NSNumber numberWithInt: 8080]]) {
                     return key;
                 }]

将其视为一个函数时:

BOOL bob(id key, id obj) {
    if( [[obj port] isEqual: [NSNumber numberWithInt: 8080]]) {
        return key;
    }
}

看到问题了吗?有一个代码路径不返回值,因此编译器会抱怨。

A little expansion on Barry's answer....

A block is just like a function pointer with one key difference. A block will infer the return type from the return statements contained within or it will give an error message like the one you said (the LLVM compiler's error should be a bit more reasonable).

When you wrote:

NSSet * mySet = [myDict keysOfEntriesPassingTest:^(id key, id obj, BOOL *stop) {
                 if( [[obj port] isEqual: [NSNumber numberWithInt: 8080]]) {
                     return key;
                 }]

Consider that as a function:

BOOL bob(id key, id obj) {
    if( [[obj port] isEqual: [NSNumber numberWithInt: 8080]]) {
        return key;
    }
}

See the problem? There is a code path that doesn't return a value and, thus, the compiler would complain.

懵少女 2024-09-12 11:44:17

该错误表明您的块必须返回 BOOL,而不是 id。检查文档。我怀疑如果密钥/对象对通过了所需的测试,您应该返回YES

The error indicates that your block must return a BOOL, rather than id. Check the docs. I suspect you are expected to return YES if the key/obj pair passes the desired test.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文