Cocoa Touch:什么发布,何时发布?

时间:2009-01-10 10:37:16

标签: iphone cocoa cocoa-touch

我正在努力了解我必须在Cocoa Touch中重新开始的时间和内容,因为它没有垃圾收集。

这个代码块来自苹果iphone示例PeriodicElements,他们发布了anElement和rawElementArray,但没有发布路径,firstLetter,existingArray和tempArray?

我原以为至少应该释放tempArray和existingArray。

有些聪明的人可以向我解释原因吗?

谢谢:)

- (void)setupElementsArray {
NSDictionary *eachElement;

// create dictionaries that contain the arrays of element data indexed by
// name
self.elementsDictionary = [NSMutableDictionary dictionary];
// physical state
self.statesDictionary = [NSMutableDictionary dictionary];
// unique first characters (for the Name index table)
self.nameIndexesDictionary = [NSMutableDictionary dictionary];

// create empty array entries in the states Dictionary or each physical state
[statesDictionary setObject:[NSMutableArray array] forKey:@"Solid"];
[statesDictionary setObject:[NSMutableArray array] forKey:@"Liquid"];
[statesDictionary setObject:[NSMutableArray array] forKey:@"Gas"];
[statesDictionary setObject:[NSMutableArray array] forKey:@"Artificial"];

// read the element data from the plist
NSString *thePath = [[NSBundle mainBundle]  pathForResource:@"Elements" ofType:@"plist"];
NSArray *rawElementsArray = [[NSArray alloc] initWithContentsOfFile:thePath];

// iterate over the values in the raw elements dictionary
for (eachElement in rawElementsArray)
{
    // create an atomic element instance for each
    AtomicElement *anElement = [[AtomicElement alloc] initWithDictionary:eachElement];

    // store that item in the elements dictionary with the name as the key
    [elementsDictionary setObject:anElement forKey:anElement.name];

    // add that element to the appropriate array in the physical state dictionary 
    [[statesDictionary objectForKey:anElement.state] addObject:anElement];

    // get the element's initial letter
    NSString *firstLetter = [anElement.name substringToIndex:1];
    NSMutableArray *existingArray;

    // if an array already exists in the name index dictionary
    // simply add the element to it, otherwise create an array
    // and add it to the name index dictionary with the letter as the key
    if (existingArray = [nameIndexesDictionary valueForKey:firstLetter]) 
    {
    [existingArray addObject:anElement];
    } else {
        NSMutableArray *tempArray = [NSMutableArray array];
        [nameIndexesDictionary setObject:tempArray forKey:firstLetter];
        [tempArray addObject:anElement];
    }

    // release the element, it is held by the various collections
    [anElement release];

}
// release the raw element data
[rawElementsArray release];



// create the dictionary containing the possible element states
// and presort the states data
self.elementPhysicalStatesArray = [NSArray arrayWithObjects:@"Solid",@"Liquid",@"Gas",@"Artificial",nil];
[self presortElementsByPhysicalState];

// presort the dictionaries now
// this could be done the first time they are requested instead

[self presortElementInitialLetterIndexes];

self.elementsSortedByNumber = [self presortElementsByNumber];
self.elementsSortedBySymbol = [self presortElementsBySymbol];

}

3 个答案:

答案 0 :(得分:4)

他们通过向类rawElementsArray发送+alloc来创建anElement,因此该对象由上面示例中的代码拥有,必须被释放。与thePath类似。请注意,tempArray+alloc不是通过发送+new-copy或{{1}}消息创建的,因此调用代码不对这些对象的生命周期负责。请看一下这个Cocoa内存管理文章集合:

http://iamleeg.blogspot.com/2008/12/cocoa-memory-management.html

答案 1 :(得分:1)

您不必释放tempArray的原因是因为它已被分配,然后立即自动释放。 Autorelease是一种在将来的某个时间安排释放调用的方法,因此API的调用者不必显式释放结果。

Matt Dillard提供了Objective C的内存管理策略的详细解释,并且比我更好地解释了它。

答案 2 :(得分:1)

约定是当你使用类方法创建一个对象时,它应该是自动释放的。这意味着在刷新自动释放池时,在运行循环结束时,将释放这些对象。但是,如果使用+ alloc] -init]或-copy,-mutableCopy或+ new(与+ alloc相同)-init创建一些内容,那么它将不会被自动释放。

例如:

NSArray *array1 = [NSArray arrayWithObject:@"foo"];
NSArray *array2 = [[NSArray alloc] initWithObject:@"foo"];

Array1将自动释放,您无需担心。需要手动释放Array2。或者你也可以这样做:

NSArray *array2 = [[[NSArray alloc] initWithObject:@"foo"] autorelease];

这几乎是+ arrayWithObject :.

当然,这会导致对实例变量的生命周期进行重要考虑。如果你使用array2创建实例变量那么它会没有问题,因为它的保留计数为1.但是,需要保留array1,否则它将在runloop的末尾自动释放,给它一个保留计数为0所以它将被释放,你将留下一个悬垂的指针。