为什么Objective-c对象必须动态分配?为什么我必须使它一个指针指向一个对象,不像在c++中,我可以创建堆栈?谢谢。
主要原因:不知道应该保留多少堆栈大小。
现有的约定和使用也使得取消限制相当困难。
动态消息传递在这种情况下并不重要,因为在初始化时设置正确的'vtable'是微不足道的。
在c++中,堆栈对象的大小总是已知的(如果是错误的,您知道会发生什么)。objc alloc/init序列可以返回几种类型中的任何一种——每种类型都有不同的大小(本质上是一个工厂),或者什么都不返回。
的大小也可以在运行时变化(例如,您可以通过运行时向类添加字段)。
更新1
我对此很好奇,所以我做了一个小测试程序作为概念证明。
i能够实现一个简单的基于objc类层次结构的堆栈,它也实现了NSObject
接口的一个很好的块——当然,省略了引用计数和动态分配接口,因为它与概念证明无关。无论如何,我的简单类层次结构不与NSObject类或协议完全兼容,因此它不应该用于期望NSObject类型的地方,原因很明显。因此,如果您真的想要基于堆栈的objc对象,那么是可能的(并且不是特别困难)。
您不必做任何与c++不同的事情来保留堆栈空间。保留的堆栈大小在某些领域仍然是一个限制(考虑工厂方法,类集群等)。
也有一些默认情况下不能工作的运行时功能。这里最好的例子是在运行时添加变量的能力。实际上,如果需要的话,您可以容纳这个功能。我懒得做那个练习。
自然地,基本接口可以有几个偏差——我做的一个有趣的偏差是增加了交换活动对象的实现(类型)的能力。
玩得开心
更新2
结果是,GCC接受了我写的概念证明。不幸的是,由于在保留正确大小时可能遇到的问题/危险(考虑到语言的动态特性……),这在clang中被禁止了。例如:clang禁止sizeof(NSObject)
。哦。
Objective-c是一种动态语言,这意味着它的一切都可以在运行时改变。对象的类对象仅在从可执行文件加载时创建,并且可以通过类别更改。此外,运行时可以为属性实例化变量。由于编译后对象的很多信息都可能发生变化,因此在使用它之前不能创建它。
这是因为Objective-C使用动态或延迟绑定的方式。不像c++,在c++中,你总是可以选择通过类的对象调用函数,还是通过同一类甚至超类的指针调用函数。在后一种情况下,需要多态性。
然而,在Objective-C中,总是存在在运行时确定正确函数的能力。不同之处在于,例如在c++中,编译器必须确保所使用的函数存在,而在Objective-C中,编译器并不真正关心,运行时系统只决定。