Цель C: выпуск и размещение

Я новичок в C и Objective C, но не могу найти этот ответ

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

Вот код:

NSString *numberString = [[NSString alloc] init];
numberString = resultLabel.text;
[self setFirstNumber:[numberString doubleValue]];
[resultLabel setText:@"0"];
[numberString release];

Я думаю, что понял, почему это из-за строки «numberString = resultLabel.text», однако я не понимаю, почему программа вылетает. Почему я не могу отпустить numberString? Если я этого не сделаю, это вызовет утечку памяти?

P.S. Я знаю, что код неуклюжий, я новичок в программировании и еще более супер новичок в Objective C.

P.S.S. Я отпускаю resultLabel позже - (void) dealloc {}


person rafal    schedule 12.07.2011    source источник


Ответы (3)


numberString - это указатель, который означает, что он будет указывать на память, которую вы ему назначаете. В первой строке да, вы вызвали alloc / init и несете ответственность за его освобождение. В следующей строке вы устанавливаете указатель на другое значение, которым вы не владеете, и исходная строка, которую вы вызвали alloc, утекла. Обращение к [[NSString alloc] init] совершенно бессмысленно, но вот ваш пример работы с выпуском.

NSString *numberString = [[NSString alloc] init]; //Not necessary
[numberString release]; //Properly released now it is safe to reassign
numberString = resultLabel.text; 
//numberString is now pointing at another object

[self setFirstNumber:[numberString doubleValue]];
[resultLabel setText:@"0"];
//No need to release it any more here

Что вам нужно сделать, так это просто установить numberString в текст и не использовать никаких вызовов освобождения.

NSString *numberString = resultLabel.text;
person Joe    schedule 12.07.2011
comment
Будет ли объект выпущен автоматически или нет, это деталь реализации. Все, что вас должно волновать, это то, владеете ли вы объектом или нет. - person albertamg; 12.07.2011

Измените первые две строки на:

NSString *numberString = [[NSString alloc] initWithString: resultLabel.text];

Поскольку экземпляр NSString неизменен, вы не можете установить его значение после его инициализации. В своем коде вы устанавливаете указатели.

person dasdom    schedule 12.07.2011
comment
Зачем вам это делать, если вы можете делать NSString *numberString = resultLabel.text; или NSString *numberString = [resultLabel.text retain]; - person JeremyP; 12.07.2011

Ты прав! Написав:

numberString = resultLabel.text;

Теперь вы ссылаетесь на экземпляр String для resultLabel.text, и когда вы пытаетесь освободить его, возникает ошибка, потому что этот String не был выделен вами, поэтому вы не должны выпускать его.

Если вы просто ссылаетесь на текст из Object позади resultLabel, просто оставьте первую строку, потому что вам просто нужна переменная типа NSString (указатель), и вам не нужен новый экземпляр NSString.

[EDIT] Как правильно упомянул dasdom, путем выделения и создания экземпляра объекта NSString в первой строке, который вы никогда не используете и который вы никогда не выпускаете (вы пытаетесь освободить NSString из метки, которая выпускается где-то еще), вы создали память утечка.

person das_weezul    schedule 12.07.2011
comment
плюс numberString - это утечка. - person dasdom; 12.07.2011