块内存管理

发布于 2024-10-02 10:14:28 字数 1066 浏览 3 评论 0原文

在 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 方法范围后会被销毁吗?

There is a conceptual overview of Blocks objects in objective-c within this Apple reference:

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

However, it does not really explain two topics that concern me and may concern other people. The first question is like that: can I assign a nil to a Block reference? Or should I use NULL? Or can I use neither of them?

The second problem lies in the sphere of memory management. Say, I have declared such a method creating a block object on the stack.

-(void)makeTheClass
{
    TheClass *object = [[TheClass alloc] init];

    object.blockReference = ^(void) { return nil; } 
}

This object, being created within some scope, is going to be destroyed after it goes out of it. But TheClass object is actually going to store a reference to this (nearly destroyed) Block:

typedef id (^WeirdBlockType)(void);

@interface TheClass {
    WeirdBlockType blockReference;   
}

How do I declare a class property for such a block?
What's the difference between these two:

@property (nonatomic, retain) WeirdBlockType blockReference;
@property (nonatomic, copy)   WeirdBlockType blockReference; 

?

It is clearly said in the Apple documentation that block copying moves the block to the heap. But what if I just retain it? Is it going to be destroyed after it goes out of makeTheClass method scope?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

与往事干杯 2024-10-09 10:14:28

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

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

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

谢谢大家!

Well I've found the solution.
Thanks to Gojan for his answer, but he was actually wrong in one place:

Wevah was right. Retain on a block has no effect until it is completely moved to the heap, and only Block_copy accomplishes such a task.

Perhaps blocks are not the only objects that cannot be retained while they are on the stack; but whilst you create (alloc and init) any NSObject subclass instances on the heap by default, you don't care about it - retain works as usual. Block objects are created on the stack by default, that's why the work a little unexpectedly.

Thanks everybody!

蔚蓝源自深海 2024-10-09 10:14:28

我可以将 nil 分配给一个块吗
参考?或者我应该使用 NULL?

nil 可以理解为“空 id 类型”,而 NULL 的定义类似于 ((void *)0)。这里的区别在于上下文。如果您正在使用基于 NSObject 的对象,则应该使用 nil。

对于块,您应该使用 nil,因为您可以与块进行交互,就像它是 NSObject 一样(您可以保留它、释放它等)。但如果你使用 NULL 它应该可以工作。

如何声明类属性
这样的块?有什么区别
两者之间:

@property(非原子,保留)WeirdBlockType blockReference;
@property(非原子,复制)WeirdBlockType blockReference; 

在文档中说:

如果你使用 Objective-C,你可以
发送块副本、保留和释放
(和自动释放)消息。

所以这两个声明都是有效的,但如果你问我,我更喜欢 retain 而不是 copy

结论:

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

can I assign a nil to a Block
reference? Or should I use NULL?

nil can be read as "an empty id type" and NULL is defined like ((void *)0). The difference here is the context. If you are working with NSObject's based objects you should use nil.

In the case of blocks you should use nil because you can interact with the block like if it was an NSObject (you can retain it, release it, etc). But if you use NULL it should work.

How do I declare a class property for
such a block? What's the difference
between these two:

@property (nonatomic, retain) WeirdBlockType blockReference;
@property (nonatomic, copy)   WeirdBlockType blockReference; 

?

In the documentation says:

If you are using Objective-C, you can
send a block copy, retain, and release
(and autorelease) messages.

So both declarations are valid, but if you ask my I prefer retain than copy.

In conclusion:

Blocks are treated like objects defined and instantiated at the same time (runtime) so after you get a perdurable reference to it you can think that reference like any other object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文