Могу ли я вернуть выделенный объект и освободить его вне функции? - PullRequest
3 голосов
/ 29 марта 2011
- (NSString *)allocString{
    NSString *str = [[NSString alloc] init];
    return str;
}

- (void)viewDidLoad{
    NSString *name = [self allocString];

    [name release]; // Can I release an object here?
}

Привет, я только что написал простой пример с использованием NSString.В моей настоящей программе вместо NSString я использовал пользовательский класс UIView.

allocString создает один экземпляр NSString, и его счетчик сохранения равен 1. Без автоматического высвобождения он просто возвращает экземпляр.

ВВ методе viewDidLoad переменная «name» просто указывает на объект, возвращаемый методом allocString, поэтому счетчик сохранения экземпляра по-прежнему равен 1.

Таким образом, [имя выпуска] уменьшает количество сохраняемых данных.

Это правильно?Или я должен автоматически выпустить его в методе allocString?Спасибо!

Ответы [ 3 ]

6 голосов
/ 29 марта 2011

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

Но что выделают не принято.Если вы хотите, чтобы объект жил по истечении срока жизни метода (чтобы вы могли return забрать его и получить его вызывающим методом), вам следует использовать autorelease.

InВ вашем примере первый метод, вероятно, не должен сохранять владение строкой.Это должно выпустить это и позволить вызывающему абоненту поднять это.Но, конечно, если вы release это в методе, он будет немедленно освобожден.Так что вместо этого вы можете autorelease.При автоматическом его освобождении ваш первый метод говорит: «Мне больше не нужен этот объект и я оставляю свое право собственности, но, пожалуйста, немного подержите его в памяти, чтобы мой вызывающий мог сохранить его, если потребуется» .

Вот пример:

- (NSString *)createString {
    /* Create a string. This method owns it. */
    NSString *str = [[NSString alloc] init];

    /* Autorelease it. This method does not own it, but wants it to stay in memory temporarily. */
    [str autorelease]

    /* Return it. It will stay in memory till the end of the current run loop */
    return str;
}

- (void)viewDidLoad{
    NSString *name = [self createString];
    /* We now have a copy of the string. Nobody owns it. */
    /* It is due to be released at the end of the current run loop. */

    /* If we want to take ownership of it and prevent deallocation, we should retain it. */
    [name retain];
}

Это поведение используется во всех API-интерфейсах Cocoa.Когда вы видите методы класса, которые возвращают новый объект, этот объект будет автоматически освобожден.Например, когда вы вызываете [NSArray arrayWithObjects:@"One", @"Two", @"Three", nil], вы просите класс NSArray создать для вас массив.Если существует вне метода arrayWithObjects:, благодаря его статусу автоматического освобождения.Если вы не retain это, он будет освобожден в конце текущего цикла выполнения.

1 голос
/ 29 марта 2011

Если вы просто замените имя метода allocString на newString, оно будет работать нормально.В цели C есть соглашение для обработки таких методов.Это соглашение заключается в том, что имя метода должно начинаться с «new *», и оно не вызовет утечки памяти.

0 голосов
/ 29 марта 2011

Да, все, что у вас там, будет работать нормально.

...