此Apple参考中的objective-c中有Blocks对象的概念性概述:
http://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Blocks/Blocks.pdf
然而,它并没有真正解释两个与我有关的主题,可能与其他人有关。第一个问题是这样的:我可以为块引用分配一个nil吗?或者我应该使用NULL?或者我可以不使用它们吗?
第二个问题在于内存管理领域。说,我已经声明了这样一个方法在堆栈上创建一个块对象。
-(void)makeTheClass
{
TheClass *object = [[TheClass alloc] init];
object.blockReference = ^(void) { return nil; }
}
这个对象是在某个范围内创建的,在它离开之后将被销毁。但是TheClass对象实际上将存储对此(几乎被破坏)块的引用:
typedef id (^WeirdBlockType)(void);
@interface TheClass {
WeirdBlockType blockReference;
}
如何为这样的块声明类属性? 这两者之间的区别是什么:
@property (nonatomic, retain) WeirdBlockType blockReference;
@property (nonatomic, copy) WeirdBlockType blockReference;
Apple文档中明确指出,块复制会将块移动到堆。但是,如果我保留它呢?它是否会在makeTheClass
方法范围之后被销毁?
答案 0 :(得分:2)
我找到了解决方案。 感谢Gojan的回答,但他在一个地方实际上是错的:
Wevah是对的。 保留一个块无效,直到它完全移到堆中,只有Block_copy
才能完成这样的任务。
也许块不是唯一在堆栈上时无法保留的对象;但是当您在堆上创建(alloc
和init
)任何NSObject
个子类实例默认时,您并不关心它 - {{1}像往常一样工作。默认情况下,块对象在堆栈上 ,这就是为什么工作有点出乎意料。
谢谢大家!
答案 1 :(得分:0)
我可以为一个块指定一个nil 参考?或者我应该使用NULL?
nil可以读作“空id
类型”,NULL定义为((void *)0)
。这里的区别在于背景。如果您正在使用NSObject的对象,则应使用nil。
在块的情况下,你应该使用nil,因为你可以与块交互,就好像它是一个NSObject(你可以保留它,释放它等)。但是如果你使用NULL它应该可以工作。
如何声明类属性 这样的一块?有什么不同 这两者之间:
@property (nonatomic, retain) WeirdBlockType blockReference; @property (nonatomic, copy) WeirdBlockType blockReference;
在文档中说:
如果您使用的是Objective-C,则可以 发送块副本,保留和释放 (和自动释放)消息。
因此两个声明都有效,但如果你问我,我更喜欢retain
而不是copy
。
总结:
块被视为同时定义和实例化的对象(运行时),因此在获得对它的持久引用后,您可以将引用视为任何其他对象。