19

我试图理解块。当直接传递给方法时,我知道如何正常使用它们。我现在有兴趣获取一个块,将它(例如)存储在一个实例变量中并稍后调用它。

块编程指南听起来我可以做到这一点,通过使用 Block_copy / retain 复制块,但是当我尝试运行它时,我的程序崩溃了。

- (void) setupStoredBlock
{
    int salt = 42;
    m_storedBlock = ^(int incoming){ return 2 + incoming + salt; };
    [m_storedBlock retain];
}

我稍后尝试调用它:

- (void) runStoredBlock
{
    int outputValue = m_storedBlock(5);
    NSLog(@"When we ran our stored blockwe got back: %d", outputValue);
    [m_storedBlock release];
}

有人有任何见解吗?(或者,有什么我没有得到的东西吗?)

非常感谢你!

4

4 回答 4

30

你会想要这样做:

- (void) setupStoredBlock
{
    int salt = 42;
    m_storedBlock = Block_copy(^(int incoming){ return 2 + incoming + salt; });
}
于 2010-04-17T17:39:01.213 回答
6

当您希望它保留时复制一个块。完成后自动释放或释放它。如果您需要很长的拼写方式,请保留它/* NOP */

@interface Foo : FooSuper {}
@property(copy) int (^storedBlock)(int);
@end

@implementation Foo
@synthesize storedBlock = mStoredBlock;

- (void)setupStoredBlock {
    self.storedBlock = ^{/*...*/};
    // or: mStoredBlock = [^{/*...*/} copy];
    // but this simple implementation violates the atomicity contract
}

- (void)runStoredBlock {
    int result = self.storedBlock(5);
    NSLog(@"%s: result = %d", __func__, result);
}
@end
于 2010-04-21T05:04:22.650 回答
6

• 与所有局部变量一样,堆栈中存在一个非静态块并将从堆栈中弹出,就像任何其他未声明为静态的局部变量一样。

• Block_copy() 将块从堆栈复制到所有 malloc 实例都存在的堆上。和所有新/复制方法一样,Block_copy() 返回一个保留计数为 1 的堆分配对象。块是一个 ObjectiveC 对象,但不像普通对象那样符合。因此,Block_Release() 和目标释放方法应该没有区别。

• 此示例使用块实例的复制方法。因为将 Block_copy() 的结果分配给一个 id 需要一个我不想出错的类型转换。复制方法允许将块变量直接分配给一个 id。

 - (void) setupStoredBlock
{
    int zStackLocalVariable = 42;
    iHeapAllocatedVariable = [^int(int aMore){ return zStackLocalVariable + aMore; } copy];
}

• 将对象声明为静态就是要求它与代码本身一起物理分配。声明为静态的块被编译器禁止访问其自身范围之外的变量。由于静态块声明的要求,我假设堆栈上的块与堆中的块有所不同。

• 块是一个objective c 对象,它的类的类名和其他相关信息我还没有尝试检索,但是,像Protocol、Object 和其他隐藏的objectiveC 类一样,它不符合NSObject。然而,像所有的objectiveC 对象一样,它必须符合retain/release。ARC 也将保留/释放等效性扩展到核心基础对象,如果不是现在,那么最终可能会扩展到 malloc/free 分配。

• 我等待彻底探索mikeash.com的真正动机,因为苹果公司喜欢让我们所有人都处于一些没有什么物理意义的超理论层面,即使所有重要的都是物理的。

ARC 和块也在这里讨论

于 2013-01-21T02:45:42.390 回答
4

在最近的 WWDC (2010) 上有一个关于这个主题的非常好的演讲。它描述了块是如何实现的以及为什么需要使用 Block_copy。您可以从演示文稿中下载电影:http: //developer.apple.com/itunes/ ?destination=adc.apple.com.4092414566 电影名称为:“高级 Objective-C 和垃圾收集”

于 2010-11-02T20:23:43.553 回答