Управление памятью на iPhone - PullRequest
0 голосов
/ 09 июня 2010

Извините, что задаю такой простой вопрос, но это конкретный вопрос, на который я не смог найти ответ.

Я не являюсь нативным программистом target-c, поэтому прошу прощения, если я использую какие-либо термины C #!

Если я определю объект в test.h

@interface test : something {
    NSString *_testString;
}

Затем инициализируйте его в test.m

-(id)init {
    _testString = [[NSString alloc] initWithString:@"hello"];
}

Тогда я понимаю, что я бы выпустил его в dealloc, поскольку каждый init должен иметь выпуск

-(void)dealloc {
    [_testString release];
}

Однако, что мне нужно пояснитьЧто происходит, если в init я использую один из ярлыков для создания объекта, я все еще выпускаю его в dealloc?Разве это не нарушает правило «один релиз для одного инициала»?например,

-(id)init {
    _testString = [NSString stringWithString:@"hello"];
}

Ответы [ 7 ]

6 голосов
/ 09 июня 2010

Есть аккуратная аббревиатура, чтобы помнить, что вы должны выпустить

NARC - новое, выделение, сохранение, копирование.

3 голосов
/ 09 июня 2010

Если он не создан с помощью alloc, new, copy, mutableCopy, вы не несете ответственности за его освобождение.

На этом сайте есть несколько хороших кратких обзоров таких вещей, как управление памятью.

Вот цитата из cocoadevcentral:

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

2 голосов
/ 09 июня 2010

Просто чтобы немного прояснить ситуацию. Когда вы получаете объект через N.A.R.C. как говорит Сильванаар, вам нужно release это. В других случаях вы получаете автоматически выпущенный объект, который будет автоматически освобожден через некоторое время. Это будет плохо в коде, который вы здесь представили, потому что вы хотите, чтобы эта строка оставалась как минимум до тех пор, пока ваш объект. Так что вам действительно нужно сделать явное retain, чтобы сохранить его для вашего объекта.

Это не прямой ответ на ваш вопрос, а скорее ожидание следующего; -)

1 голос
/ 09 июня 2010

Если вы установите атрибут с автоматическим выпуском, объект в атрибуте может умереть в любое время за пределами непосредственной области видимости. Удобные методы, то есть те, которые начинаются с типа: строка, массив, словарь и т. Д., Возвращают автоматически выпущенные объекты. Вы используете автоматически выпущенные объекты только тогда, когда вам все равно, выживут ли они за пределами существующей области.

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

Если вы делаете:

@property(nonatomic, retain)  NSString *_testString; // .h
@synthesize _testString; //.m

тогда в коде используйте справочную форму:

self._testString = [NSString stringWithString:@"hello"];

... тогда единственное место, которое вы должны освободить _testString, находится в dealloc. Компилятор создаст синтезированные средства доступа, которые будут автоматически управлять памятью свойств для вас.

Кстати, вы не должны использовать подчеркивания для имен. Apple оставляет за собой имена подчеркивания, чтобы вы могли столкнуться с именами.

0 голосов
/ 09 июня 2010

Наоборот, вам нужно сохранить объект, который вы получаете от stringWithString:.Как вы правильно заметили, вам не принадлежит этот объект и, следовательно, вам не нужно его освобождать.Но поскольку вы им не владеете, он может в любое время исчезнуть, что приведет к краху, если вам повезет (и очень странная ошибка, если вы этого не сделаете).Таким образом, вам нужно сохранить объект, а затем вам сделать необходимо выпустить его в dealloc.

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

0 голосов
/ 09 июня 2010

В первой части примера у вас действительно должен быть релиз для строки где-то.

Во второй части примера, поскольку он автоматически выпущен, вам не нужно вызывать дополнительный релизв методе dealloc.Это на самом деле вызовет сбой, когда вы пытаетесь отправить сообщение на то, что больше не существует ...

0 голосов
/ 09 июня 2010

Правило таково: если вы создаете объект с новым, alloc, copy или сохраняете его, вам нужно его освободить.Нельзя освобождать объекты, созданные любым другим способом.

Так что в вашем конкретном случае вам не нужно освобождать строку, созданную с помощью stringWithString.

Кстати, я бы порекомендовал Какао и Objective-C: Up and Running книга для получения дополнительной информации о таких вещах.Отличное введение, если вы новичок в программировании Какао.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...