I'm trying to understand blocks. I get how to use them normally, when passed directly to a method. I'm interested now in taking a block, storing it (say) in an instance variable and calling it later.
我试图了解块。当直接传递给方法时,我得到了正常使用它们的方法。我现在感兴趣的是一个块,将它(比如说)存储在一个实例变量中并稍后调用它。
The blocks programming guide makes it sound like I can do this, by using Block_copy / retain to copy the block away, but when I try to run it I crash my program.
块编程指南听起来像我可以这样做,通过使用Block_copy / retain来复制块,但是当我尝试运行它时,我崩溃了我的程序。
- (void) setupStoredBlock
{
int salt = 42;
m_storedBlock = ^(int incoming){ return 2 + incoming + salt; };
[m_storedBlock retain];
}
I try to call it later:
我试着稍后再说:
- (void) runStoredBlock
{
int outputValue = m_storedBlock(5);
NSLog(@"When we ran our stored blockwe got back: %d", outputValue);
[m_storedBlock release];
}
Anyone have any insights? (Or, is there something I'm not getting with blocks?)
有人有任何见解吗? (或者,有什么东西我没有用积木?)
Thank you very much!
非常感谢你!
4 个解决方案
#1
30
You'll want to do this instead:
你会想要这样做:
- (void) setupStoredBlock
{
int salt = 42;
m_storedBlock = Block_copy(^(int incoming){ return 2 + incoming + salt; });
}
#2
6
Copy a block when you want it to stay around. Autorelease or release it when you're through with it. Retain it if you need a long way to spell /* NOP */
.
当您希望它留在身边时复制一个块。当你完成它时,自动释放或释放它。如果你需要很长的拼写/ * 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
#3
6
• Like all local variables, a non-static block exists on the stack and will be popped from the stack, like any other local variable which has not been declared static.
•与所有局部变量一样,堆栈上存在非静态块,并且将从堆栈中弹出,就像任何其他未声明为静态的局部变量一样。
• Block_copy() copies the block from the stack onto the heap, where all malloc instances exist. And like all new/copy methods, Block_copy() returns a heap allocated object with a retain count of 1. A block is an objectiveC object but doesNot conform like a normal object. Therefore, there should be no difference between Block_Release() and the objective release method.
•Block_copy()将块从堆栈复制到堆上,其中存在所有malloc实例。和所有新的/复制方法一样,Block_copy()返回一个堆分配的对象,其保留计数为1.块是一个objectiveC对象,但不像普通对象那样符合。因此,Block_Release()和目标释放方法之间应该没有区别。
• This example uses the copy method of a block instance. Because assigning the result of a Block_copy() to an id requires a type cast that I doNot want to get wrong. The copy method allows the block variable to be assigned directly to an id.
•此示例使用块实例的复制方法。因为将Block_copy()的结果分配给id需要一个我不希望出错的类型转换。复制方法允许将块变量直接分配给id。
- (void) setupStoredBlock
{
int zStackLocalVariable = 42;
iHeapAllocatedVariable = [^int(int aMore){ return zStackLocalVariable + aMore; } copy];
}
• To declare an object static is to require it to be physically allocated with the code itself. A block which is declared static is compiler prohibited from accessing variables outside of its own scope. Due to the requirements of a static block declaration, I assume that the block on the stack is somehow different from the block which is in the heap.
•声明一个静态对象是要求它与代码本身进行物理分配。声明为static的块是编译器禁止访问其自身范围之外的变量。由于静态块声明的要求,我假设堆栈上的块与堆中的块有某种不同。
• A block is an objective c object whose class whose class name and other associated information I have not yet attempted to retrieve, but, like Protocol, Object and other hidden objectiveC classes, it does not conform to NSObject. Like all objectiveC objects, however, it must conform to retain/release. ARC extends retain/release equivalencies into Core Foundation objects as well, and probably, if not now, then eventually, into malloc/free allocations.
•块是一个客观的c对象,其类的类名和其他相关信息我尚未尝试检索,但是,如Protocol,Object和其他隐藏的objectiveC类,它不符合NSObject。但是,与所有objectiveC对象一样,它必须符合retain / release。 ARC还将保留/释放等效项扩展到Core Foundation对象中,如果不是现在,最终可能会延伸到malloc / free分配中。
• I await the true motivation for a thorough exploration of mikeash.com, as apple likes to keep us all on some hyper-theoritical plane of little physical significance, even though all that is significant is physical.
•我等待彻底探索mikeash.com的真正动机,因为苹果喜欢把我们所有人放在一些物理意义不大的超理论层面上,尽管所有重要的东西都是物理的。
ARC and blocks also discussed here
ARC和块也在这里讨论
#4
4
There were a very nice presentation on that subject on recent WWDC (2010). It described how blocks were implemented and why you need to use Block_copy. You can download a movie from the presentation at: http://developer.apple.com/itunes/?destination=adc.apple.com.4092414566 The movie is called: "Advanced Objective-C and garbage collection"
在最近的WWDC(2010)上有关于该主题的非常好的演示。它描述了如何实现块以及为什么需要使用Block_copy。您可以从演示文稿下载电影:http://developer.apple.com/itunes/?destination = admin.apple.com.4092414566这部电影名为:“高级Objective-C和垃圾收集”
#1
30
You'll want to do this instead:
你会想要这样做:
- (void) setupStoredBlock
{
int salt = 42;
m_storedBlock = Block_copy(^(int incoming){ return 2 + incoming + salt; });
}
#2
6
Copy a block when you want it to stay around. Autorelease or release it when you're through with it. Retain it if you need a long way to spell /* NOP */
.
当您希望它留在身边时复制一个块。当你完成它时,自动释放或释放它。如果你需要很长的拼写/ * 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
#3
6
• Like all local variables, a non-static block exists on the stack and will be popped from the stack, like any other local variable which has not been declared static.
•与所有局部变量一样,堆栈上存在非静态块,并且将从堆栈中弹出,就像任何其他未声明为静态的局部变量一样。
• Block_copy() copies the block from the stack onto the heap, where all malloc instances exist. And like all new/copy methods, Block_copy() returns a heap allocated object with a retain count of 1. A block is an objectiveC object but doesNot conform like a normal object. Therefore, there should be no difference between Block_Release() and the objective release method.
•Block_copy()将块从堆栈复制到堆上,其中存在所有malloc实例。和所有新的/复制方法一样,Block_copy()返回一个堆分配的对象,其保留计数为1.块是一个objectiveC对象,但不像普通对象那样符合。因此,Block_Release()和目标释放方法之间应该没有区别。
• This example uses the copy method of a block instance. Because assigning the result of a Block_copy() to an id requires a type cast that I doNot want to get wrong. The copy method allows the block variable to be assigned directly to an id.
•此示例使用块实例的复制方法。因为将Block_copy()的结果分配给id需要一个我不希望出错的类型转换。复制方法允许将块变量直接分配给id。
- (void) setupStoredBlock
{
int zStackLocalVariable = 42;
iHeapAllocatedVariable = [^int(int aMore){ return zStackLocalVariable + aMore; } copy];
}
• To declare an object static is to require it to be physically allocated with the code itself. A block which is declared static is compiler prohibited from accessing variables outside of its own scope. Due to the requirements of a static block declaration, I assume that the block on the stack is somehow different from the block which is in the heap.
•声明一个静态对象是要求它与代码本身进行物理分配。声明为static的块是编译器禁止访问其自身范围之外的变量。由于静态块声明的要求,我假设堆栈上的块与堆中的块有某种不同。
• A block is an objective c object whose class whose class name and other associated information I have not yet attempted to retrieve, but, like Protocol, Object and other hidden objectiveC classes, it does not conform to NSObject. Like all objectiveC objects, however, it must conform to retain/release. ARC extends retain/release equivalencies into Core Foundation objects as well, and probably, if not now, then eventually, into malloc/free allocations.
•块是一个客观的c对象,其类的类名和其他相关信息我尚未尝试检索,但是,如Protocol,Object和其他隐藏的objectiveC类,它不符合NSObject。但是,与所有objectiveC对象一样,它必须符合retain / release。 ARC还将保留/释放等效项扩展到Core Foundation对象中,如果不是现在,最终可能会延伸到malloc / free分配中。
• I await the true motivation for a thorough exploration of mikeash.com, as apple likes to keep us all on some hyper-theoritical plane of little physical significance, even though all that is significant is physical.
•我等待彻底探索mikeash.com的真正动机,因为苹果喜欢把我们所有人放在一些物理意义不大的超理论层面上,尽管所有重要的东西都是物理的。
ARC and blocks also discussed here
ARC和块也在这里讨论
#4
4
There were a very nice presentation on that subject on recent WWDC (2010). It described how blocks were implemented and why you need to use Block_copy. You can download a movie from the presentation at: http://developer.apple.com/itunes/?destination=adc.apple.com.4092414566 The movie is called: "Advanced Objective-C and garbage collection"
在最近的WWDC(2010)上有关于该主题的非常好的演示。它描述了如何实现块以及为什么需要使用Block_copy。您可以从演示文稿下载电影:http://developer.apple.com/itunes/?destination = admin.apple.com.4092414566这部电影名为:“高级Objective-C和垃圾收集”