Проблемным контекстом является ViewController с несколькими обработчиками кнопок и файлом данных Scores.list из 1000 объектов NSString. Если я нажимаю на buttonOne, код обработчика проверяет, существует ли файл Scores.list в каталоге пользовательских документов. Если да, он загружает данные в NSMutableArray с именем Score, если нет, он создает NSMutableArray в памяти (для последующего хранения на диске) следующим образом:
- (void)readScores
{
// Setup path + filename pathUserDocDirScorelist);
...
// test for presence scores.list in documents dir
if ([fileManager fileExistsAtPath: pathUserDocDirScorelist])
{ // Read scores.plist into NSMutableArray
score = [NSMutableArray arrayWithContentsOfFile:pathUserDocDirScorelist];
} else { // Initialize empty scores array with 1000 empty NSString entries
score = [[NSMutableArray alloc] init];
int i;
for(i = 0; i < 1000; i++) {
[score addObject:@""];
}
}
// at this point there is always a valid array score with 1000 entries
}
В основном этот код работает; в обоих случаях (чтение данных из Scores.list или сборка in-mem) я могу проверить в отладчике (с помощью 'po Score'), что массив с 1000 записями присутствует впоследствии.
Теперь приходит проблема, которая блокирует меня на 2 дня:
В обработчике buttonTwo такие операторы, как [count count], аварийно завершают работу, но только в том случае, если оценка массива получает данные с диска, а не при накоплении в памяти. В первом случае это массив остается в силе, хотя до последней строки кода обработчика buttonOne, но затем «испаряется», как только массив обращается к следующему обработчику (EXC_BAD_ACCESS).
Нет, это не вызвано преждевременным заявлением о выпуске, так как его нет (пока) во всем моем приложении. :)
(пока не касается утечек памяти).
Как это возможно, что в одном представлении NSMutableArray действителен в конце обработчика кнопки 1, но недействителен в начале следующего обработчика кнопки 2, если между ними не выполняется явный оператор освобождения?
Дополнительная информация:
ViewController.h
@interface ViewController : UIViewController {
NSMutableArray *score;
...
}
@property (nonatomic, retain) NSMutableArray *score;
...
- (IBAction) buttonOne: (id) sender;
- (IBAction) buttonTwo: (id) sender;
@end
А в ViewController.m у меня есть:
@synthesize score;
...
- (IBAction) buttonOne: (id) sender {
if (score == nil) {
[self readScores];
}
...
NSLog(@"Number of entries in score = %i", [score count]); // never crashes
}
- (IBAction) buttonTwo: (id) sender {
NSLog(@"Number of entries in score = %i", [score count]); // **crash point**
}
P.S. Я попробовал NSZombieEnabled, запустив приложение с помощью alt / cmd / R и добавив «NSZombieEnabled = YES», но это не приводит к дополнительной информации в консоли отладки.