我正在努力了解我必须在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];
}
答案 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所以它将被释放,你将留下一个悬垂的指针。