在Objective C中为实例变量赋值

时间:2009-03-25 20:54:03

标签: objective-c instance-variables

我正在看的功能:

-(void)viewDidLoad {
    NSBundle *bundle = [NSBundle mainBundle];
    NSString *plistPath = [bundle pathForResource:@"statedictionary" ofType:@"plist"];

    NSDictionary *dictionary = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
    self.statesZips = dictionary;
    [dictionary release];

    NSArray *components = [self.stateZips allKeys];
    NSArray *sorted = [components sortedArrayUsingSelector:@selector(compare:)];
    self.States = sorted;

    NSString *selectedState = [self.states objectAtIndex:0];
    NSArray *array = [stateZips objectForKey: selectedState];
    self.zips = array;  
}

为什么要分配NSDictionary,然后分配给一个名为* dictionary的指针,然后分配给实例变量stateZips?为什么不分配它并将其直接分配给实例变量并节省创建和释放另一个NSDictionary的内存?总是遵循相同的方法,包括后来在NSArray的这个函数......

NSDictionary *dictionary = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
self.statesZips = dictionary;
[dictionary release];

此外,此排序按字母顺序放置哈希表(字典)中的键。我不确定我理解这一行:

NSArray *sorted = [components sortedArrayUsingSelector:@selector(compare:)];

3 个答案:

答案 0 :(得分:6)

似乎没有人解决这条线的事实

self.statesZips = dictionary;

不是直接的实例变量赋值。 stateZips是一个属性,因此该代码行调用setStateZips:方法。该方法保留或复制字典,因此除非viewDidLoad方法打算再次出于某种目的使用它,否则不再需要它。这样就可以release了。

上一行:

[[NSDictionary alloc] initWithContentsOfFile:plistPath];

分配一个对象。这使你有责任release一旦你不再需要它。在将其分配给statesZips属性后,不再需要它,因此它已经发布,您不应再使用dictionary。您会注意到以后的代码只引用self.stateZips,而不是dictionary

对于方法中稍后的NSArrayviewDidLoad不分配对象,因此该方法不负责在其上调用release。经验法则是,如果你alloc它,你有责任确保它被释放。否则,这不是你的问题。

对数组进行排序使用sortedArrayUsingSelector:方法。选择器标识Objective-C中的方法。 @selector是选择器的文字语法(有点像@""NSString个对象的文字语法。那么,该代码所说的是“给我一个数组,其中components中的对象被排序,并使用compare:方法在进行排序时比较每个对象。当它对数组进行排序时,它会在数组中的对象上调用compare:来确定如何将它们按顺序排列。

答案 1 :(得分:4)

可能保留statesZips属性,这就是推理。

首次分配NSDictionary时,其保留计数为1.当它被分配给statesZips时,保留计数变为2.当它被释放时,保留计数降至1,这通常是期望的结果。

请注意,下面的代码会产生(几乎)相同的结果:

self.statesZips = [NSDictionary dictionaryWithContentsOfFile:plistPath];

因为dictionaryWithContentsOfFile返回一个自动释放的对象。

作为惯例,像[NSDictionary dictionary]这样的类方法返回自动释放的对象(一段时间后会自动释放),而通常的alloc-init方法(如[[NSDictionary alloc] init]中)返回保留的对象。

我建议您阅读Memory Management Programming Guide for Cocoa以获取更多信息。

编辑:当我第一次阅读时,我一定错过了你问题的最后一部分,但巴里已经回答了那部分内容。

答案 2 :(得分:2)

此代码使用引用计数内存管理(而不是OS X上Objective-C 2.0中提供的自动垃圾收集内存管理)。当分配任何对象(在本例中为NSDictionary和NSArray)时,调用者负责在该实例上调用-release。未能调用释放会导致内存泄漏。代码可以写成

self.statesZips = [[[NSDictionary alloc] initWithContentsOfFile:plistPath] autorelease];

但代价是显式内存管理不明确(依赖NSAutoreleasePool在事件循环迭代结束时释放alloc'd实例。

电话

[components sortedArrayUsingSelector:@selector(compare:)];

返回一个数组,其元素来自components但是根据调用[elem1 compare:elem2]的返回值来比较两个数组元素。