Сбой при выпуске NSArray app

#objective-c #ios #memory-management

#objective-c #iOS #управление памятью

Вопрос:

Я пытаюсь «маркировать» свои данные, которые я получаю из своего текстового файла.

Когда я делаю это, я получаю ошибку, подобную этой:

malloc: * ошибка для объекта 0x844c730: освобождаемый указатель не был выделен * установите точку останова в malloc_error_break для отладки

Код, который я использую, выглядит следующим образом:

 NSString *filePath = [[NSBundle mainBundle] pathForResource:@"mydata" ofType:@"txt"];
NSString *rawText = [NSString stringWithContentsOfFile:filePath encoding:NSASCIIStringEncoding error:nil];
//No error was caused by above line
NSArray *tmp = [rawText componentsSeparatedByString:@"##@@"];
NSString *title = @"";
NSString *detail = @"";
for(int i = 0; i < [tmp count]-1; i  )
{
    NSArray *base = [[tmp objectAtIndex:i] componentsSeparatedByString:@"##"];
    title = [[NSString alloc] initWithFormat:@"%@$$%@",title,[base objectAtIndex:0]];
    detail = [[NSString alloc] initWithFormat:@"%@$$%@ | %@ | %@",
              title,
              [base objectAtIndex:0],
              [base objectAtIndex:1],
              [base objectAtIndex:2]
              ];
    [base release];
}
[tmp release];
  

Это должна быть эта часть кода, поскольку, если я прокомментирую этот фрагмент, он будет работать нормально.

Читая сообщение об ошибке, set a breakpoint которое я понятия не имею, как это сделать malloc_error_break

Что не так в моем управлении памятью?

Или иначе, как я могу разделить строку каким-либо другим способом?

Комментарии:

1. Вы уверены, что сбой вызван выпуском NSArray? Оставляет ли программа EXC_BAD_ACCESS или что-то в этой строке?

2. Ах, это оставляет EXC_BAD_ACCESS но не там, в main.m

3. EXC_BAD_ACCESS в main.m бесполезен. Вы всегда должны добавлять точку останова для генерируемых исключений, используя кнопку добавить в навигаторе точек останова / боковой панели. Это приведет к прерыванию работы отладчика в строке, которая вызвала исключение not main.m

Ответ №1:

Вы получили tmp от componentsSeparatedByString: . Поскольку этот селектор не начинается с «alloc» или «new» или «copy» или «mutableCopy», и поскольку вы этого не делали [tmp retain] , вы не являетесь владельцем tmp . Так что вам не следует делать [tmp release] .

То же самое для base .

Комментарии:

1. Я все еще пытаюсь разобраться с памятью. Занимаюсь Java уже 3 года :/ — спасибо!

2. Если вы загуглите для управления памятью objective-c , вы найдете несколько хороших вводных (включая Apple). Но если вам, возможно, удастся избежать необходимости использования iOS 5, ARC (автоматический подсчет ссылок) сделает это еще проще.

Ответ №2:

Base и temp являются autorelease объектами, поэтому вы не должны освобождать эти объекты.

Ответ №3:

Вам не нужно выпускать base . Оно уже автоматически выпущено.

Ответ №4:

Вы пытаетесь освободить базу массива, не выделяя ее. NSArray *base = [[tmp objectAtIndex:i] componentsSeparatedByString:@»##»]; не выделил память для базы.Вам не нужен [базовый выпуск]; пока он не будет выделен.

Комментарии:

1. Конечно, componentsSeparatedByString: выделяется память. Но возвращаемый массив автоматически освобождается. Это просто означает, что текущий пул автоматического выпуска выпустит объект для вас позже.