Question

- (NSString *)allocString{
    NSString *str = [[NSString alloc] init];
    return str;
}

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

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

Hi, I just wrote a simple example using NSString. In my real program, instead of NSString, I used a custom UIView class.

allocString creates one NSString instance and its retain count is 1. Without autoreleasing, it just returns an instance.

In viewDidLoad method, a variable "name" just points to an object returned by allocString method, so an instance's retain count is still 1.

Thus, [name release] decreases its retain count.

Is this right? Or do I have to autorelease it in allocString method? Thank you!

Was it helpful?

Solution

What you have done will work. You can retain and release objects from any scope you choose, so long as it all evens out (and the object is deallocated when it is no longer needed by any other object).

But what you are doing is not conventional. If you want to allow the object to live on past the life of a method (so that you can return it and have it picked up by the method caller) then you should use autorelease.

In your example, the first method should probably not retain ownership of the string. It should release it and let the caller pick it up. But, of course, if you release it in the method it will be instantly deallocated. So instead you can autorelease it. By autoreleasing it, your first method is saying "I no longer need this object and relinquish my ownership, but please keep it in memory a little while longer so my caller can retain it if it needs to".

Here's an example:

- (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];
}

This behaviour is used all throughout the Cocoa APIs. When you see class methods that return a new object, that object will be autoreleased. For example, when you call [NSArray arrayWithObjects:@"One", @"Two", @"Three", nil] you are asking the NSArray class to create an array for you. If exists outside of the arrayWithObjects: method thanks to its autoreleased status. If you do not retain it, it will be released at the end of the current run loop.

OTHER TIPS

If you just replace "allocString" method name to "newString", it works fine. There's a convention in objective C to handle such methods. That convention is that the method name should start with "new*" and it will not throw any memory leak.

Yes, everything you have there will work just fine.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top