使用中介来初始化对象

时间:2011-07-24 13:24:18

标签: objective-c cocoa initialization properties conventions

我一直看到我们使用中间对象,例如,创建一个数组来填充另一个数组:

characters = [[NSArray alloc] initWithObjects:@"Antony", @"Artemidorus", @"Brutus", nil];  
play.characters = characters;  
[characters release];  

characters在对象NSArray中为play

我在@property及其self看到同样的事情:我们没有将新项直接添加到此属性中,就像我们没有直接填写characters一样上面的例子。这只是关于“风格”吗?

2 个答案:

答案 0 :(得分:2)

这不是风格问题。

play.characters是一个属性,可以“包含”现有数组或nil,但即使它“包含”现有数组,也无法更改{{1}的内容1}},所以你必须创建一个新的并将其分配给属性。

如果声明了所有属性,则分配给属性将导致其setter方法运行(可以由编译器创建,如果您使用NSArray,或者由您在代码中编写),那将会注意删除任何现有阵列,分配新阵列并保留它。

答案 1 :(得分:1)

在这段小代码中实际上只有一个数组在运行。

数组不是中间数组,而是包含指针的变量 - 在本例中是变量字符。

这就是:

表达式

[[NSArray alloc] initWithObjects:@"Antony", @"Artemidorus", @"Brutus", nil] 

分配一个对象并使用三个NSStrings(它们本身就是对象)进行初始化,但让我们暂时搁置一下。初始化还包括保留计数的增量,因此从一开始就是一个。

这个新创建的对象位于内存中的给定位置,比如0100H。然后将该位置存储在变量characters中。在C语言中,我们说characters是指向对象的指针。

然后,对象@"characters"的属性play被设置为指向内存中与局部变量characters相同的位置。因此,现在有两个变量(其中一个也是属性)指向同一个对象,或者,如果您愿意,则指向内存中的相同位置。如果属性的类型为retain,则会自动增加对象的保留计数,因此现在为2。

使用最后一行中的release消息,对象将其保留计数减1,因此在此代码段的末尾,play.characters属性指向该对象,并且它具有保留计数一个。

要非常干净,这段代码应该将局部变量设置为nil,以避免在持有指向对象的指针和保留计数的变量之间产生混淆。

所有这些都是为了表明这里确实只有一个数组在运行,但有两个变量指向它。因此,乍看之下,没有多少计算机资源被浪费。

如果你想在一行中完成所有这些,你可以这样写:

play.characters = [[[NSArray alloc] initWithObjects:@"Antony", @"Artemidorus", @"Brutus", nil] autorelease];

但其确切的工作原理不太清楚,因为它涉及其中一个神秘的自动释放,即一个自动处理并推迟到某个后期的版本。

这是一个很长的描述,但我希望它能说明正在发生的事情。