【问题标题】:Blocks memory management块内存管理
【发布时间】:2010-11-13 11:51:59
【问题描述】:

在这个 Apple 参考中,objective-c 中有一个 Blocks 对象的概念概述:

http://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Blocks/Blocks.pdf

但是,它并没有真正解释两个与我有关且可能与其他人有关的主题。第一个问题是这样的:我可以将 nil 分配给 Block 引用吗?或者我应该使用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方法作用域后会被销毁吗?

【问题讨论】:

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


    【解决方案1】:

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

    Wevah 是对的。 在块上的保留没有任何作用,直到它完全移动到堆中,并且只有 Block_copy 才能完成这样的任务。

    也许块不是唯一在堆栈中无法保留的对象;但是当你在堆上创建(allocinit)任何NSObject 子类实例时默认,你并不关心它 - retain 照常工作。块对象是默认在堆栈上创建的,这就是为什么工作有点出乎意料。

    谢谢大家!

    【讨论】:

    • 我仍在努力解决这个问题,但我认为“在块上保留 [literal] 没有效果”这句话并不完全正确:它确实增加了阻止对吗?但是它仍然会在堆栈上,所以我想这确实没什么用,因为一旦我们离开堆栈框架,它就会被丢弃。我可能在这里回答了我自己的疑问:) 只是想知道这是否有意义。还是谢谢。
    【解决方案2】:

    我可以将 nil 分配给 Block 参考?还是应该使用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

    总结:

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

    【讨论】:

    • 如果你想让一个块在它声明的范围之外持续存在,你必须复制它。
    猜你喜欢
    • 2016-10-01
    • 2011-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多