2011-07-24 61 views
0

我始终认为,我们所使用的中间对象,例如,创建一个数组来填补另一个数组:使用中介的初始化对象

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

characters的对象是一个NSArrayplay

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

回答

1

实际上在这小段代码中只有一个阵列正在播放。

它不是中间数组,而是变量持有指向它的指针 - 在这种情况下是变量字符。

这是发生了什么:

表达

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

分配一个对象,有三个NSString的(它们本身是对象,但让我们留下了一会儿)初始化它。初始化还包括保留计数的增量,所以它是一个起点。

这个新创建的对象位于内存中的某个特定位置,比如0100H。这个位置然后被存储在变量characters中。用C术语来说,characters是一个指向对象的指针。

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

随着最后一行中的释放消息,对象将其保留计数递减1,因此在此代码片段的末尾,该对象由play.characters属性指向,并且其保留计数为1。

要真正干净,这段代码可能应该设置局部变量为nil,以避免变量之间持有指向对象的指针和保留计数之间的混淆。

所有这些都是为了表明这里真的只有一个数组,而是指向它的两个变量。所以没有太多的计算机资源被乍一看看浪费了。

如果你想做到这一切在一个单一的线,你可以写这样的事情:

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

但这个确切的工作还不太清楚,因为它涉及到那些神秘的自动释放的一个,即一个自动处理并推迟到稍后阶段的发布。

这是一个很长的描述,但我希望它能说明发生了什么。

+0

感谢Monolo,很好的回答,现在它更有意义。干杯 – Paul

+0

嗨Monolo,我只是问:在相同的代码中,我发现:NSString * cellText = nil; cellText = play.genre;在DetailVC中,我们可以编写一个指针,把一些数据放在里面,甚至不用alloc-init NSString,因为我们有对象Play的“保留”,是吗?再次感谢 – Paul

+0

如果变量cellText在方法中的一组大括号(范围)内定义,**和**您分配发生在同一范围内,**和**'play.genre'未被赋值其他东西(这意味着它保存的对象会失去保留计数),是的。 – Monolo

2

这不是一个风格的问题。

play.characters是一个属性,并可以“​​包含”一个现有的阵列或nil,但即使“包含”现有的阵列,你不能改变一个NSArray的内容,所以你必须创建一个新的,并分配给该属性。

如果声明了所有声明,那么分配给属性将导致其setter方法运行(如果您使用@synthesize或由您编写代码,则可由编译器创建),并且将处理删除任何现有阵列,分配新阵列并保留它。

+0

好的谢谢它是有道理的,谢谢你的回复! – Paul