【问题标题】:Storing a block with a parameter inside a NSArray在 NSArray 中存储带有参数的块
【发布时间】:2013-05-01 22:45:37
【问题描述】:

我知道我可以定义一个像块这样的属性,比如:

self.myProperty = ^(){
   // bla bla bla        
};

将其存储在数组中

NSArray *arrayOfBlocks = [[NSArray alloc] initWithObject:[self.myProperty copy]];

然后使用执行它

void (^ myblock)() = [arrayOfBlocks objectAtIndex:0];
myblock();

但是如果块有参数呢?

我的意思是,像这样的块:

self.myProperty = ^(id myObject){
   // bla bla bla        
};

我想要的是能够保持这条线不变

void (^ myblock)() = [arrayOfBlocks objectAtIndex:0];
myblock();

// yes, I know I can replace myblock(); with myblock(object);
// but because I have a large number of blocks on this array, I will have to build
// a huge if if if if statements to see what block is being run and change the objects passed

我想要的是将带有参数的块存储在数组上......像这样:

NSArray *arrayOfBlocks = [[NSArray alloc] initWithObject:[self.myProperty(object?) copy]];

这可能吗?

【问题讨论】:

    标签: ios cocoa-touch objective-c-blocks


    【解决方案1】:

    幸运的是,块是一流的值。您可以创建一个工厂方法,该方法返回一个块,该块将被某个对象调用。

    typedef void (^CallbackBlock)(void);
    - (CallbackBlock)callbackWithNumber:(int)n
    {
        return [^{
            NSLog(@"Block called with %d", n);
        } copy];
    }
    

    用法:

    [mutableArray addObject:[self callbackWithNumber:42]];
    [mutableArray addObject:[self callbackWithNumber:1337]];
    
    // later:
    CallbackBlock cb = [mutableArray objectAtIndex:0];
    cb();
    

    【讨论】:

    • 封装参数和块的想法非常巧妙。这是黑魔法!谢谢!
    • @RubberDuck 欢迎。是的,这是非常简洁的东西,我非常喜欢闭包;)
    • 嗨@H2CO3 在从 callbackWithNumber: 返回之前将副本发送到块时是否存在内存管理问题?该块被添加到数组中,但它永远不会被释放!这种情况下真的有必要复制吗?
    • 错误答案;上面的代码没有解决问题。除非在提供 n 的值的相同范围内调用该块,否则 n 会丢失。如果您从任何其他方法从数组中检索块,应用程序将崩溃。
    猜你喜欢
    • 2012-02-28
    • 1970-01-01
    • 1970-01-01
    • 2018-04-27
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多