Я уже некоторое время пытаюсь устранить эту утечку памяти, поэтому я надеюсь, что сообщество сможет оказать некоторую помощь. Управление памятью все еще остается проблемой, над которой я работаю (да, у меня есть руководство по управлению памятью).
Согласно инструменту «Утечка инструментов», я пропускаю NSArray, как только перехожу назад (кнопка назад с Nav Controller) с соответствующего экрана. Ниже я показываю весь соответствующий код, который могу придумать, и могу поделиться большим, если это необходимо.
Я знаю, что я выделяю / инициирую массив в упорядоченной функции массива. Это потому, что, насколько я понимаю, 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 в View Controller
#import <UIKit/UIKit.h>
@class InstalledDataTracker;
@interface SBVC_LSC01_ZoneSelect : UIViewController <UITableViewDataSource, UITableViewDelegate> {
... other stuff...
InstalledDataTracker *_dataTracker;
}
@property (nonatomic, retain) InstalledDataTracker *dataTracker;
.m init в View Controller
@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, приводят к некоторому сбою / неправильному доступу в контроллере представления. Это способствует моей путанице из-за того, где правильно освобождать массив ...
Подробные ответы очень приветствуются. Мне еще предстоит многому научиться!
Спасибо большое. (Кроме того, мне пришлось изменить некоторые имена классов и методов для обеспечения безопасности проекта, поэтому, если что-то не соответствует, пожалуйста, сообщите об этом, и я перепроверю для опечатки)
Edit:
@ Дэниел Хикс, когда я удаляю копию initWithArray
отсортированного массива следующим образом:
orderedZonesArray = [unorderedZones sortedArrayUsingSelector:@selector(localizedCompare:)];
, я получаю сбой EXC_BAD_ACCESS, когда класс пытается получить доступ к массиву из метода View Controller didSelectRowAtIndexPath
(вероятно, при следующем доступе к массиву, я полагаю). Вот метод. Он вылетает во второй строке 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];
}