Когда сохранять NSString? - PullRequest
       44

Когда сохранять NSString?

1 голос
/ 26 октября 2011

Когда объект NSString передается в качестве аргумента, я должен всегда делать retain и release:

-forExample:(NSString*)str{
    [str retain];

    //do something

    [str release];
}

или нет?Где и когда я должен использовать это?

Ответы [ 2 ]

4 голосов
/ 26 октября 2011

Счетчик ссылок этого объекта не будет меняться в течение этого метода, поэтому нет причины отправлять его retain.Из эссе Apple Memory Management (которое вы обязательно должны просмотреть):

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

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

- (void) forExample: (NSString *)theString {
    // Will need this object later. Stuff it into an ivar and retain it.
    // myString = [theString retain];    
    // For NSString, it's actually better to copy, because this
    // could be a _mutable_ string, and it would in fact be best to use
    // the setter for the ivar, which should deal with the memory management:
    [self setMyString:theString];

    // Do things...

    // Don't release.
}

Если вы сохранили объект, вам нужно отправить его release, когда он вам больше не нужен.

- (void) otherExample {
    [myString doYourStringThing];
    // If you don't need the string past this point (which would be slightly
    // unusual -- it leaves an ivar unset) release it and set it to nil.
    // [myString release]; myString = nil;
    // Again, it would be best to use the setter:
    [self setMyString:nil];
}

// Generally you keep ivars around until the instance is deallocated,
// and release them in dealloc
- (void) dealloc {
    [myString release];
    [super dealloc];
}
0 голосов
/ 26 октября 2011

Вы никогда не должны этого делать, потому что, как хороший разработчик, вы следите за последними тенденциями в Objective-C и используете Автоматический подсчет ссылок .Автоматический подсчет ссылок устраняет необходимость вручную вызывать удержание / отпускание и поставляется с LLVM 3.0 и Xcode 4.2.

Если по какой-то причине вы хотите использовать ручное управление памятью, как здесь, вам не следуетвручную звоните retain и release в большинстве случаев.Обычно вполне нормально использовать свое суждение и не сохранять каждый аргумент индивидуально.

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

Пример такого сценария :

- (void)myFunction:(NSString *)foo block:(void (^)())callback {
    [foo retain];
    callback();
    // .. do some stuff
    [foo release];
}

- (void)myCallingFunction {
    NSString * myVariable = [[NSString alloc] initWithString:@"Test"];
    [self myFunction:myVariable block:^ {
        [myVariable release];
    }];
}

Как видите, код [myVariable release] будет достигнут до комментария // .. do some stuff.

...