2011-04-23 39 views
0

让我们想象我有分数类。因此,创建它的实例的正确方法是:如何在Objective C中声明类的实例?

Fraction *myFraction; 
or 
myFraction = Fraction; 
or 
myFraction = [Fraction new]; 

还是别的什么?

在这本书中,我正在研究正确的是第一个,但它对我来说看起来不合理。为什么我们必须为它创建一个指针?我们为什么不制作真实的实例?

第一个表达式意味着 - 给我一个指向Fraction类新实例的指针,不是吗?

+0

请注意,您可以[将行格式化为代码](http://meta.stackexchange.com/questions/22186/how-do-i-format-my-code-blocks)缩进四个空格。编辑器工具栏中的“{}”按钮可以为您做到这一点。编辑你的问题并尝试一下。单击编辑器工具栏中的橙色问号以获取更多信息和格式化提示。 – outis 2011-04-23 09:02:26

回答

4

第一个声明类型为Fraction *的名为myFraction的变量,但不会创建任何内容,也不会初始化myFraction。第二个是无效的。第三个创建一个新的Fraction并将其分配给之前声明的名为myFraction的变量。通常在Objective-C,你会声明在一个语句初始化变量:

Fraction *myFraction = [[Fraction alloc] init]; 

至于是否使用之后initnewalloc,这在很大程度上是口味的问题。

用于存储对象的变量部分是指针,因为Objective-C继承了C的call-by-value语义。当一个变量被分配给另一个变量时(例如将其传递给函数时),该值将被复制。最好的情况是,这对于不可变对象是无效的。最糟糕的是,它会导致不正确的行为。指针是一种绕过值调用和copy-on-assign语义的方式:具有指针类型的变量值就是指针。可以在不触及目标物体的情况下进行复制。这是你需要某种形式memory management的成本。

0

为什么我们必须为它创建一个指针?我们为什么不制作真实的实例?

在Objective-C中,每个对象都是指针类型。因此,您需要使用newalloc/init

Fraction *myFraction = [ Fraction new ] ; 

Fraction *myFraction = [ [Fraction alloc] init ] ; 

而且myFraction需要被释放。

第一个表达式意味着 - 给我一个指向Fraction类新实例的指针,不是吗?

不,您只是宣布了类型Fraction的指针。而第二种说法甚至不是有效的。

3

阅读Kernihan和Ritchie的“The C Programming Language”是个好主意,这样你就可以了解变量是如何声明的。

在C和Obj-C和C++中有两种分配模式:手册自动

整数和浮点数和字符等通常会自动声明。它们是在声明通过时创建的(即int i),并且在它们创建的范围消失时(即退出声明的块时)将被删除。它们被称为自动装置。 (也可以将它们声明为“静态”,但对于关于分配的讨论而言,这些是相同的)

对象太复杂,无法传递给函数,因为函数参数是“按值传递”,意思是该参数获取传入的值的副本,而不是变量本身。需要花费大量的时间来复制整个对象。

由于这个原因,你想告诉他们可以找到对象的各种功能。不要交出对象的副本,而是交出对象地址的副本。该地址被自动存储,其类型为指针。 (这实际上只是一个整数,但它的大小是由硬件和操作系统决定的,因此它需要是特殊类型。)

声明Fraction * myFraction;的意思是“myFraction是一个指针,只是你知道,它会在稍后指向一个分数。”

这会自动分配指针,但不是整个分数。为此,您必须致电allocinit

为什么你有这两个步骤的过程的一个重要原因是,因为我们通常希望对象坚持一段时间,所以我们不希望系统在函数结束时自动将它们杀死。我们需要他们坚持下去。我们创造了将物体挂在我们的功能上的地方,但是那些衣架在不需要时会消失。我们不希望他们与他们一起接受对象。

最终,你可能会做出的声明是这样的:

Fraction *myFraction = [[Fraction alloc] initWithNumerator: 2 Denominator: 3]; 

它说:“让我一小部分,并且将其设置为2/3,然后把那部分的地址为‘myFraction’ “。