在Objective-C中复制块(即:将它们复制到实例变量)

时间:2010-04-17 16:19:43

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

我正在试图了解块。当直接传递给方法时,我得到了正常使用它们的方法。我现在感兴趣的是一个块,将它(例如)存储在一个实例变量中并稍后调用它。

块编程指南听起来像我可以这样做,通过使用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 个答案:

答案 0 :(得分:30)

你会想要这样做:

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

答案 1 :(得分: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

答案 2 :(得分: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];
}

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

•一个块是一个客观的c对象,其类的类名和其他相关信息我尚未尝试检索,但是,如Protocol,Object和其他隐藏的objectiveC类,它不符合NSObject。但是,与所有objectiveC对象一样,它必须符合retain / release。 ARC还将保留/释放等效项扩展到Core Foundation对象中,如果不是现在,最终可能扩展到malloc / free分配。

•我等待彻底探索mikeash.com的真正动机,因为苹果喜欢把我们所有人放在一些物理意义不大的超理论层面上,尽管所有重要的都是物理的。

ARC and blocks also discussed here

答案 3 :(得分:4)

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