【发布时间】:2011-11-29 06:05:52
【问题描述】:
我一直在努力解决这个内存泄漏问题,所以我希望社区可以提供一些帮助。内存管理仍然是我正在努力理解的一个问题(是的,我有内存管理指南)。
根据 Instruments Leak 工具,当我从相关屏幕向后导航(带导航控制器的后退按钮)时,我正在泄漏 NSArray。我在下面展示了我能想到的所有相关代码,如果需要可以分享更多。
我知道我正在有序数组函数中分配/初始化一个数组。这是因为,据我所知,sortedArrayUsingSelector 只返回指向旧数组的指针,而不是真正的副本,所以如果我想保留数组,我需要复制这些值。
问题是我如何将这个排序后的数组传递给不同的类,同时仍然正确地管理我对它的所有权?我在 dealloc 中释放它,如果函数要分配一个新值等,我会释放它。但是我不知道我是否正确地这样做了。
就像我说的,我真的很难正确理解如何正确处理所有内存管理的东西,所以任何帮助都将不胜感激。
相关模型类的.h文件
@interface InstalledDataTracker : NSObject {
...other code...
NSArray *orderedZonesArray;
...other code...
}
@property (nonatomic, retain) NSArray *orderedZonesArray;
相关模型类的.m文件
@synthesize orderedZonesArray;
...other code...
- (NSArray *)orderedZonesArray {
if (!orderedZonesArray || installedDataChangedSinceLastRead) {
if (orderedZonesArray) {
[orderedZonesArray release];
}
NSArray *unorderedZones = [NSArray arrayWithArray:[self.installedAreas allKeys]];
orderedZonesArray = [[NSArray alloc] initWithArray:[unorderedZones sortedArrayUsingSelector:@selector(localizedCompare:)]];
}
return orderedZonesArray;
}
- (void) dealloc {
...other code...
[orderedZonesArray release], orderedZonesArray = nil;
[super dealloc];
}
视图控制器中的.h
#import <UIKit/UIKit.h>
@class InstalledDataTracker;
@interface SBVC_LSC01_ZoneSelect : UIViewController <UITableViewDataSource, UITableViewDelegate> {
... other stuff...
InstalledDataTracker *_dataTracker;
}
@property (nonatomic, retain) InstalledDataTracker *dataTracker;
.m 在视图控制器中初始化
@synthesize dataTracker = _dataTracker;
- (id)initWithPerson:(NSString *)person {
if (self = [super init]) {
...other stuff...
self.dataTracker = [[InstalledDataTracker alloc] init];
}
return self;
}
- (void)dealloc
{
...other stuff...
[self.dataTracker release];
[super dealloc];
}
视图控制器中的泄漏方法
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
AbbreviationLookup *lookup = [[AbbreviationLookup alloc] init];
NSString *abbreviatedZone = [self.dataTracker.orderedZonesArray objectAtIndex:[indexPath section]];
cell.textLabel.text = [lookup zoneForAbbreviation:abbreviatedZone];
[lookup release];
return cell;
}
仪器泄漏跟踪:
0 libSystem.B.dylib calloc
1 libobjc.A.dylib class_createInstance
2 CoreFoundation __CFAllocateObject2
3 CoreFoundation +[__NSArrayI __new::]
4 CoreFoundation -[NSArray initWithArray:range:copyItems:]
5 CoreFoundation -[NSArray initWithArray:]
6 -[InstalledDataTracker orderedZonesArray]
7 -[SBVC_LSC01_ZoneSelect tableView:cellForRowAtIndexPath:]
我尝试过的事情
orderedZonesArray = [[[NSArray alloc] initWithArray:[unorderedZones sortedArrayUsingSelector:@selector(localizedCompare:)]] autorelease];
return [orderedZonesArray autorelease];
还有一堆我不记得的东西。我为正确“释放”由 alloc/init 创建的所有权所做的许多尝试导致视图控制器中出现某种崩溃/错误访问。这导致我对正确释放数组的位置感到困惑......
欢迎详细回复。我还有很多东西要学!
非常感谢。 (另外,为了项目的安全,我不得不更改一些类和方法的名称,所以如果有些东西看起来不匹配,请提及,我会重新检查是否有错字)
编辑:
@Daniel Hicks,当我删除排序数组的initWithArray 副本时,如下:
orderedZonesArray = [unorderedZones sortedArrayUsingSelector:@selector(localizedCompare:)];
,当类尝试从视图控制器didSelectRowAtIndexPath 方法中访问数组时,我得到一个 EXC_BAD_ACCESS 崩溃(我相信下一次访问数组时可能)。这是方法。它在第二个 NSLog 行上崩溃了,所以我把它留在了一个很好的衡量标准:
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"indexPath = %@", indexPath);
NSLog(@"self.dataTracker.orderedZonesArray = %@", self.dataTracker.orderedZonesArray);
NSString *abbreviatedZone = [self.dataTracker.orderedZonesArray objectAtIndex:[indexPath section]];
SBVC_LSC02_ZoneSelect *slz2 = [[SBVC_LSC02_ZoneSelect alloc] initWithPerson:self.selectedPerson andZone:abbreviatedZone];
[self.navigationController pushViewController:slz2 animated:YES];
[slz2 release];
}
【问题讨论】:
标签: iphone sorting memory-management memory-leaks nsarray