让我们想象一下我有Fraction课程。因此,创建它的实例的正确方法是:
Fraction *myFraction;
or
myFraction = Fraction;
or
myFraction = [Fraction new];
或其他什么?
在我正在研究的书中,正确的是第一个,但这对我来说是不合理的。为什么我们必须为它创建一个指针?为什么我们不做真实的实例?
第一个表达式意味着 - 给我一个指向Fraction类的新实例的指针,不是吗?
答案 0 :(得分:4)
第一个声明名为myFraction
的{{1}}类型的变量,但不创建任何内容,也不初始化Fraction *
。第二个无效。第三个创建一个新的myFraction
并将其分配给先前声明的名为Fraction
的变量。通常在Objective-C中,您将在单个语句中声明和初始化变量:
myFraction
至于是否使用Fraction *myFraction = [[Fraction alloc] init];
或new
后跟alloc
,这主要是品味问题。
用于存储对象的变量部分是指针,因为Objective-C继承了C的call-by-value语义。将一个变量分配给另一个变量时(例如将其传递给函数时),将复制该值。充其量,这对于不可变对象来说效率低下。在最坏的情况下,它会导致错误的行为。指针是一种绕过值调用和分配时复制语义的方法:具有指针类型的变量的值只是指针。可以在不触摸目标对象的情况下复制它。这需要花费memory management。
答案 1 :(得分:3)
阅读Kernihan和Ritchie的“C编程语言”是个好主意,这样你就可以了解变量的声明方式。
C和Obj-C和C ++有两种分配模式:手动和自动。
通常会自动声明整数和浮点数以及字符等。它们是在声明通过时创建的(即 int i ),并在创建它们的范围消失时删除,即当您退出声明它们的块时。它们被称为 automatics 。 (也可以将它们声明为“静态”,但就本次讨论的分配而言,这些是相同的)
对象太复杂而无法传递给函数,因为函数参数是“按值传递”,这意味着参数获取传入的值的副本,而不是变量本身。
需要花费大量时间来复制整个对象。
出于这个原因,您只想告诉他们可以找到对象的各种功能。您不必交出对象的副本,而是递交对象地址的副本。地址存储在自动类型指针中。 (这实际上只是一个整数,但它的大小由硬件和操作系统决定,所以它需要是一种特殊的类型。)
声明 Fraction * myFraction; 表示“myFraction是一个指针,只是你知道,它稍后会指向一个Fraction。”
这将自动分配指针,但不会分配整个分数。要做到这一点,您必须调用 alloc 和 init 。
你有这两步过程的一个重要原因是,由于我们通常希望对象停留一段时间,我们不希望系统在函数结束时自动杀死它们。我们需要他们坚持下去。我们创建了将对象悬挂在我们的功能中的地方,但是当不需要时,这些衣架就会消失。我们不希望他们带着对象。
最终,你可以做出这样的声明:
Fraction *myFraction = [[Fraction alloc] initWithNumerator: 2 Denominator: 3];
其中说:“让我成为一个分数,并将其设置为2/3,然后将该分数的地址放入'myFraction'。”
答案 2 :(得分:0)
为什么我们必须为它创建一个指针?为什么我们不做真实的实例?
在Objective-C中,每个对象都是指针类型。因此,您需要使用new
或alloc/init
。
Fraction *myFraction = [ Fraction new ] ;
或
Fraction *myFraction = [ [Fraction alloc] init ] ;
需要释放myFraction
。
第一个表达式意味着 - 给我一个指向Fraction类的新实例的指针,不是吗?
不,您只是声明了Fraction
类型的指针。而第二个声明甚至没有效。