为什么必须动态分配Objective-C对象?

时间:2011-04-30 19:58:54

标签: cocoa foundation objective-c-runtime dynamic-allocation static-allocation

为什么必须动态分配Objective-c对象?为什么我必须使它成为指向对象的指针,与C ++不同,我可以在堆栈上创建它们? 感谢。

3 个答案:

答案 0 :(得分:15)

主要原因:不知道要保留多少堆栈大小。

现有的惯例和用途也使解除限制变得非常困难。

在这种情况下,动态消息传递并不重要,因为在初始化时设置正确的'vtable'是微不足道的。

在c ++中,堆栈对象的大小总是已知的(如果它错了,你知道会发生什么)。一个objc alloc / init序列可以返回几种类型中的任何一种 - 每种类型都有不同的大小(它本质上是一个工厂),或者根本没有。

大小也可以在运行时变化(例如,您可以通过运行时向类添加字段)。

更新1

我对此很好奇,所以我做了一个小测试程序作为概念证明。

我能够实现一个简单的基于堆栈的objc类层次结构,它也实现了一大块NSObject的接口 - 当然,省略了引用计数和动态分配接口,因为它与概念证明。无论如何,我的简单类层次结构与NSObject类或协议完全兼容,因此,出于显而易见的原因,它不应该在需要NSObject类型的地方使用。因此,如果您真的想要基于堆栈的objc对象, 可能(并不是特别困难)实现这一点。

您不必执行与c ++不同的任何操作来保留堆栈空间。要保留的堆栈大小在某些方面仍然是一个限制(考虑工厂方法,类集群等)。

还有一些运行时功能在默认情况下不起作用。这里最好的例子是在运行时添加ivars的能力。如果你需要它,你实际上可以容纳这个功能。我没有打扰这项运动。

自然地,基本界面可能会有几个偏差 - 我为了好玩而做的一个偏差就是增加了交换生物对象的实现(类型)的能力。

玩得开心

更新2

事实证明,GCC接受了我写的概念证明。不幸的是,由于在保留正确尺寸时可能遇到的问题/危险(考虑到语言的动态特征......),这已经被禁止了。例如:clang禁止sizeof(NSObject)。哦,好吧。

答案 1 :(得分:2)

Objective-c是一种动态语言,这意味着它的所有内容都可以在运行时更改。对象的类对象仅在从可执行文件加载时创建,并且可以按类别进行更改。此外,运行时可以为属性实例变量。由于对象在编译后可以更改,因此在使用之前无法创建。

答案 2 :(得分:1)

这是因为Objective-C使用动态或后期绑定的方式。与C ++不同,在C ++中,您总是可以选择通过它的对象调用类的函数,还是通过同一类甚至超类的指针调用。在后一种情况下,需要多态性。

但是,在Objective-C中,始终存在在运行时确定正确函数的能力。不同之处在于,例如在C ++中,编译器必须确保使用的函数存在,而在Objective-C中,编译器并不关心,运行时系统只决定。