objective-c – Obj-C Block可以自行执行吗?

这是这个问题的扩展:
Is it possible to create a category of the “Block” object in Objective-C.

基本上虽然似乎可以通过NSObject或NSBlock在块上创建类别,但我无法理解块如何能够自我评估.在最后一个问题的答案中给出的例子:

- (void) doFoo {
  //do something awesome with self,a block
  //however,you can't do "self()".  
  //You'll have to cast it to a block-type variable and use that
}

意味着有可能以某种方式将self转换为块变量,但是如何执行块本身呢?例如,假设我在NSBlock上做了一个类别,并在一个方法中做了:

NSBlock* selfAsBlock = (NSBlock*)self;

是否有任何消息可以发送给selfAsBlock以对块进行评估?

解决方法

Implies that it is possible to somehow cast self to a block variable

像这样:

- (void)doFoo {
    // Assume the block receives an int,returns an int,// and cast self to the corresponding block type
    int (^selfBlock)(int) = (int (^)(int))self;

    // Call itself and print the return value
    printf("in doFoo: %d\n",selfBlock(42));
}

请注意(在大多数情况下)您需要修复块签名,以便编译器能够根据目标平台ABI设置调用站点.在上面的示例中,签名是返回类型int,类型为int的单个参数.

一个完整的例子是:

#import <Foundation/Foundation.h>
#import <objc/runtime.h>

@interface Foo : NSObject
- (void)doFoo;
@end

@implementation Foo
- (void)doFoo {
    // Assume the block receives an int,selfBlock(42));
}
@end

int main(void) {
    [NSAutoreleasePool new];

    // From Dave's answer
    Method m = class_getInstanceMethod([Foo class],@selector(doFoo));
    IMP doFoo = method_getImplementation(m);
    const char *type = method_getTypeEncoding(m);
    Class nsblock = NSClassFromString(@"NSBlock");
    class_addMethod(nsblock,@selector(doFoo),doFoo,type);

    // A block that receives an int,returns an int
    int (^doubler)(int) = ^int(int someNumber){ return someNumber + someNumber; };

    // Call the category method which in turn calls itself (the block)
    [doubler doFoo];

    return 0;
}

相关文章

对象的传值与返回说起函数,就不免要谈谈函数的参数和返回值...
从实现装饰者模式中思考C++指针和引用的选择最近在看...
关于vtordisp知多少?我相信不少人看到这篇文章,多半是来自...
那些陌生的C++关键字学过程序语言的人相信对关键字并...
命令行下的树形打印最近在处理代码分析问题时,需要将代码的...
虚函数与虚继承寻踪封装、继承、多态是面向对象语言的三大特...