NSString EXC_BAD_ACCESS - PullRequest
       1

NSString EXC_BAD_ACCESS

4 голосов
/ 28 августа 2010

Я застрял со следующим битом кода.

NSString *gridRef = [[NSString alloc] initWithFormat: @"%@", [converter LatLongToOSGrid: latLong]];
NSLog(@"Grid Ref: %@", gridRef);
self.answerLabel.text = [[NSString alloc] initWithFormat: @"%@", gridRef];

Когда я регистрирую gridRef, он отображает правильный результат. Однако установка строки answerLabel.text вызывает ошибку EXC_BAD_ACCESS, и программа падает. ИБ подключен к правильному ярлыку, в чем проблема?

Спасибо


Я обновил код следующим образом:

    - (IBAction)convertLatLong {
    NSArray *latLong = [[NSArray alloc] initWithObjects: latTextField.text, longTextField.text, nil];

    GridRefsConverter *converter = [[GridRefsConverter alloc] init];

    NSString *gridRef = [[NSString alloc] initWithFormat: @"%@", [converter LatLongToOSGrid: latLong]];
    NSLog(@"Grid Ref: %@", gridRef);
    NSLog(@"Label: %@", self.answerLabel.text);
    answerLabel.text = @"Yippy";
    self.answerLabel.text = gridRef;

    [gridRef release];
    [converter release];
    [latLong release];
}

answerLabel инициализируется через @property @synthesize, когда контроллер представления помещается в стек. (Я не знаю, как он получает init'd, кроме того, что это одна из волшебных вещей, которые IB делает для вас. Или так, я полагаю. Я использовал точно такой же метод в других контроллерах представления и не имел этой проблемы.


Я нашел виновных - вопрос в том, как мне их освободить?

NSString *eString = [[NSString alloc] initWithFormat: @"%f", e];
NSString *nString = [[NSString alloc] initWithFormat: @"%f", n];
eString = [eString stringByPaddingToLength: (digits/2) withString: @"0" startingAtIndex: 0];
nString = [nString stringByPaddingToLength: (digits/2) withString: @"0" startingAtIndex: 0];
NSString *theGridRef = [letterPair stringByAppendingString: eString];
theGridRef = [theGridRef stringByAppendingString: nString];
[eString release];
[nString release];

return theGridRef;

и

NSArray *gridRef = [[NSArray alloc] init];
gridRef = [gridRef arrayByAddingObject: [NSNumber numberWithDouble: E]];
gridRef = [gridRef arrayByAddingObject: [NSNumber numberWithDouble: N]];
gridRef = [gridRef arrayByAddingObject: [NSNumber numberWithInteger: 8]];

NSString *theGridRef = [[NSString alloc] initWithFormat: @"%@", [self gridRefNumberToLetter: gridRef]];

[gridRef release];
[theGridRef autorelease];

return theGridRef;

} * * тысяча двадцать-один

Ответы [ 5 ]

4 голосов
/ 28 августа 2010

Вы должны включить обнаружение зомби, установив для переменной среды NSZombieEnabled значение YES, чтобы вы могли видеть, какой объект вызывает плохой доступ (не забудьте удалить это снова, когда обнаружите ошибку).

Также вы можете использовать Инструменты, чтобы найти место, где объект фактически освобождается. Для этого запустите новую сессию Instruments и используйте инструмент «Allocations». В настройках прибора установите флажок «Включить обнаружение NSZombie» и «Записать счетчик ссылок». При запуске сеанса вы нарушите место возникновения ошибки и увидите запись всех сохранений / выпусков.

Одним из мест, где вы можете быстро просмотреть, если ваш объект освобожден неправильно, является метод -viewDidUnload, где вы должны освободить выход и установить для него значение nil . Если вы забудете последний вариант и каким-то образом получите доступ к розетке, это приведет к EXC_BAD_ACCESS.

Отредактировано в соответствии с вашим обновлением:

Проблема в том, что вы присваиваете eString (и nString) новую строку, которая была alloc / init-ed. Затем вы переопределяете те из следующих операторов, потому что -stringByPaddingToLength: (как и все другие методы -stringBy...) возвращают новый и автоматически освобожденный строковый объект. Таким образом, вы потеряли ссылку на старую строку, что означает утечку памяти. Кроме того, в конце вы явно освобождаете уже автоматически освобожденные объекты, что приводит к неправильному доступу.

Вместо этого вы должны создавать автоматически выпущенные строки с самого начала ([NSString stringWithFormat: ...]) и не освобождать их в конце.

0 голосов
/ 28 августа 2010

Хорошо, проблема была в попытке освободить строки NSS, поэтому я прекратил это делать, и проблема была решена.

Может кто-нибудь объяснить, как строки сохраняются и освобождаются.У меня сложилось впечатление, что:

string = @"My String"; автоматически выпущен.NSString *string = [[NSString alloc] init...]; не выпускается автоматически, его необходимо выполнить вручную.

0 голосов
/ 28 августа 2010

Возможно, метка не вставлена ​​в этот момент в вашем коде, попробуйте проверить это.Почему вы выделяете новую строку NSString?Просто сделай:

self.label.text = gridRef;
[gridRef release];
0 голосов
/ 28 августа 2010

как создается answerLabel?Возможно, вам придется сохранить это.Или вам, возможно, нужно выпустить некоторые вещи (gridRef)?

Я не вижу других проблем с вашим кодом.

Вы можете (и, вероятно, должны) установить

* 1006.*

gridRef уже является строкой NSSt, поэтому вам не нужно выделять ее снова.

EXC_BAD_ACCESS - это, как правило, вещь памяти, связанная с несбалансированностью вашего счетчика сохранения / выпуска (или в моем большом опыте этого: стр.)

0 голосов
/ 28 августа 2010

Проверьте, действительно ли asnwerLabel не равно нулю.Вам также следует изменить эту строку:

self.answerLabel.text = [[NSString alloc] initWithFormat: @"%@", gridRef];

Кому:

self.answerLabel.text = [NSString stringWithFormat: @"%@", gridRef];

В противном случае в этой строке будет утечка памяти.

...