Вам нужно прочитать Какао Правила управления памятью .Эта строка:
subtotal = [subtotal stringByAppendingString:digit];
Имеет две вещи, которые имеют отношение к правилам управления памятью.
Это дает вам строку, которая вам не принадлежит , так как метод не начинается с new
или alloc
или содержит copy
.Это означает, что в будущем он исчезнет без вашего ведома.Если вы хотите прекратить это, вы заявляете о своем праве собственности, сохраняя его.
Он перезаписывает ссылку на предыдущее значение промежуточного итога.Если вы владели этим объектом, теперь он просочился.Вы должны сначала выпустить его.
Чтобы исправить код:
Сначала удалите
subtotal = [[NSString alloc]init];
из viewDidLoad.Это бессмысленно, так как просто устанавливает промежуточный итог для пустой строки.Используйте это вместо этого:
subtotal = @"";
Постоянные строковые литералы никогда не исчезают, так как, хотя технически вы должны сохранить его, вы можете забыть, что без каких-либо плохих последствий.необходимо освободить старое значение строки, потому что вы собираетесь заменить его.Есть два способа сделать это.Либо сохраните его во временную переменную и отпустите после добавления, либо выполните автоматическое восстановление перед добавлением.Также вам нужно сохранить новое значение.например,
NSString* temp = [subtotal];
subtotal = [subtotal stringByAppendingString: digit];
[subtotal retain];
[temp release];
или
[subtotal autorelease];
subtotal = [subtotal stringByAppendingString: digit];
[subtotal retain];
Вы также должны убедиться, что промежуточный итог выпущен в dealloc
Сказав все это, гораздо лучше использоватьсвойства, чтобы сделать как можно больше управления памятью.Объявите свойство в @interface
таким образом:
@property (copy) NSString* subtotal; // string properties should normally be copy
В реализации вам необходимо его синтезировать.Тогда viewDidLoad содержит
[self setSubtotal: @""];
, а ваше действие содержит
[self setSubtotal: [[self subtotal] stringByAppendingString: digit]];
Вам все еще нужно release
в dealloc
.