returns 阻止的方法

Method that returns block

我写了一个可以与点符号一起使用的方法,使用块技巧

- (RaginiDBQuery *(^)(id object))where;

可以使用点表示法调用此方法,因为它基本上不接收任何参数(接收,但使用返回的块)

所以我可以这样称呼它:

query.where(object)

我需要它而不是得到一个 id object 我想在这个方法中收到类似的东西:

- (NSEnumerator *)where:(BOOL (^)(id object))predicate;

这个方法可以这样调用:

[object where:^(id a){return [a intValue]%2 == 1}];

我想要的是将两者结合起来,使用点符号调用我的方法 where,但是像上面的例子一样向它发送一个谓词块,我试过这个:

- (RaginiDBQuery *(^)(BOOL (^)(id object))where;

但这给了我错误,所以问题是:

如何声明一个块,它需要一个块?

编辑:

对于任何在下面寻找答案的人,这里是 tl;dr

- (RaginiDBQuery *(^)(BOOL(^filterBlock)(id object)))where;

首先,你在做坏事。你应该把你的困难当作它是一个误入歧途的目标的证据。 Objective-C 不是 C# 或 Java 甚至 Swift。是 Objective-C。如果要使用点符号来调用 iOS 上的函数,请使用 Swift。不要试图将 Objective-C 强加到其他语言的模型中。

其次,使用typedefs.

#import <Foundation/Foundation.h>

typedef BOOL (^MyObject_wherePredicate)(id object);
typedef NSEnumerator *(^MyObject_whereReturn)(MyObject_wherePredicate);

@interface MyObject: NSObject

- (MyObject_whereReturn)where;

@end

@implementation MyObject

- (MyObject_whereReturn)where {
    return ^(MyObject_wherePredicate predicate) {
        NSArray *array = @[ @"hello", @"world", @"this", @"is", @"a", @"test" ];
        NSPredicate *p = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
            return predicate(evaluatedObject);
        }];
        return [array filteredArrayUsingPredicate:p].objectEnumerator;
    };
}

@end

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        MyObject *it = [[MyObject alloc] init];
        NSEnumerator *e = it.where(^(id object){
            NSString *string = object;
            return [string containsString:@"s"];
        });
        for (NSString *item in e) {
            NSLog(@"%@", item);
        }
    }
    return 0;
}

输出:

2015-05-31 12:34:31.191 commandline[1881:82976] this
2015-05-31 12:34:31.192 commandline[1881:82976] is
2015-05-31 12:34:31.192 commandline[1881:82976] test

先声明一个块如何?

BOOL (^myPredicate)(id) = ^BOOL(a)
{
    return [a intValue]%2 == 1;
}

然后像这样声明你想要的方法

- (RaginiDBQuery *(^)(myPredicate predicate))where;

唯一的错误基本上是缺少右括号。正确的写法应该是:

- (RaginiDBQuery *(^)(BOOL(^)(id))) where;

稍后可以通过

调用
self.where(^BOOL(id obj) {return [obj intValue] % 2 == 1;});

然而,出于可读性考虑,强烈建议按照 rob 的建议使用 typedef,否则将很难理解要传入的内容以及从函数返回的内容。