Ultimately, the behavior is determined by the implementation of NSString - just use keep / release correctly in each case and you will be safe.
what can happen: NSString literals are immortal. you can write while (1) { [@"String" release]; } while (1) { [@"String" release]; } and there will be no problems.
the ctor copy that you called most likely returns a pointer to a string literal. in pseudo code:
- (id)initWithString:(NSString *)str { self = [super init]; if (self != nil) { if ([str _isStringLiteral] || [str _isImmutable]) { [self release]; return [str retain]; } ... }
in this case, you are returned a pointer to a string literal when it passes through [[NSString alloc] initWithString:stringLiteral] . since sending release to an immortal string literal does nothing, you can understand why it is still a valid object, following what you might assume is a freed object.
never rely on such details / optimizations, just use normal lifetimes and reference counting and everything will be all right.
source share