سؤال

I have two rookie questions about memory management in non-ARC project without GC: in Objective C,when I 'autorelease' object and return it from method, should I 'release' it in the "parent method" calling the method retuning the object?

The second question is, that I returned object (f.e. user) from method (instance method on another object, f.e. userService) and saved it to property (self.userProp, self instantiated the object userService and called his method). When I released the object userService (whose method returned the object user, stored in property self.userProp), it released also the object stored in property (object user stored in property self.userProp). Why? Who was the owner of the object in property?

Thank you

هل كانت مفيدة؟

المحلول

when I 'autorelease' object and return it from method, should I 'release' it in the "parent method" calling the method retuning the object?

No. Here's why. Let's layout an example exactly as you've said:

-(NSObject*)someMethodThatReturnsAnAutoreleasedObject {
    return [[[NSObject alloc]init]autorelease];
}

-(void)myMethod {
    NSObject *obj = [self someMethodThatReturnsAnAutoreleasedObject];
    [obj doSomething];
    [obj release] //PROBLEM!
}

Look at the retain count of the objects step by step, and you'll see that while the -autorelease may not immediately cause an issue for you, it will at some later date (because -autorelease'd objects aren't "auto-released", rather they are deallocated en masse when their owning pool is drained or deallocated). The method that returns an autoreleased object returns it with an eventual retain count of 0 (0 (start) + 1 (alloc) - 1 (autorelease)), so you releasing it is not only unnecessary, but will cause a crash.

The second question is, that I returned object (f.e. user) from method (instance method on another object, f.e. userService) and saved it to property (self.userProp, self instantiated the object userService and called his method). When I released the object userService (whose method returned the object user, stored in property self.userProp), it released also the object stored in property (object user stored in property self.userProp). Why? Who was the owner of the object in property?

Again, a little setup first (this is rather convoluted at first, but makes complete sense afte you see what you're doing).

-(NSUserService*)someMethodThatReturnsAnAutoreleasedObject {
    return [[[NSUserService alloc]init]autorelease];
}

-(void)myMethod {
    self.userservice = [self someMethodThatReturnsAnAutoreleasedObject];
    [obj doSomething];
    [obj release] //No problem, assuming userService is declared retain or strong.
}

Well, why is this different? Memory qualifiers, that's why! When you declare a property, you declare a set of memory qualifiers to tell the compiler what kind of modifier to append to the assignment sign. Most properties are declared retain or strong ((under ARC), and hopefully your userService one is declared as such, as well) if they are object types, which makes the compiler interpret

self.userservice = [self someMethodThatReturnsAnAutoreleasedObject];

as

self.userservice = [[self someMethodThatReturnsAnAutoreleasedObject]retain];

Therefore, you must release it, or you have a leak on your hands (0 (start) + 1 (alloc) - 1 (autorelease) + 1 (retain) = +1).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top