我正在试图了解块。当直接传递给方法时,我得到了正常使用它们的方法。我现在感兴趣的是一个块,将它(例如)存储在一个实例变量中并稍后调用它。
块编程指南听起来像我可以这样做,通过使用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];
}
任何人都有任何见解? (或者,有什么东西我没有用积木吗?)
非常感谢!
答案 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的真正动机,因为苹果喜欢把我们所有人放在一些物理意义不大的超理论层面上,尽管所有重要的都是物理的。
答案 3 :(得分:4)
在最近的WWDC(2010)上有关于该主题的非常好的演讲。它描述了如何实现块以及为什么需要使用Block_copy。您可以从演示文稿下载电影: http://developer.apple.com/itunes/?destination=adc.apple.com.4092414566 该电影被称为:“高级Objective-C和垃圾收集”