阻止内存管理

时间:2010-11-13 11:52:00

标签: objective-c memory-management objective-c-blocks

此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方法范围之后被销毁?

2 个答案:

答案 0 :(得分:2)

我找到了解决方案。 感谢Gojan的回答,但他在一个地方实际上是错的:

Wevah是对的。 保留一个块无效,直到它完全移到堆中,只有Block_copy才能完成这样的任务。

也许块不是唯一在堆栈上时无法保留的对象;但是当您在堆上创建(allocinit)任何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

总结:

块被视为同时定义和实例化的对象(运行时),因此在获得对它的持久引用后,您可以将引用视为任何其他对象。