I am very new to Objective-C and was reading through memory management. I was trying to play around a bit with the NSAutoreleasePool but somehow it wont release my object.
I have a class with a setter and getter which basically sets a NSString *name. After releasing the pool I tried to NSLog the object and it still works but I guess it should not?
@interface TestClass : NSObject
{
NSString *name;
}
- (void) setName: (NSString *) string;
- (NSString *) name;
@end
@implementation TestClass
- (void) setName: (NSString *) string
{
name = string;
}
- (NSString *) name
{
return name;
}
@end
int main (int argc, const char * argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
TestClass *var = [[TestClass alloc] init];
[var setName:@"Chris"];
[var autorelease];
[pool release];
// This should not be possible?
NSLog(@"%@",[var name]);
return 0;
}
Your code has several problems. First, you do neither copy
nor retain
the string stored into the name
instance variable. So, if the string is released by whoever stored it into the property, you are left with a dangling reference. You should do
- (void) setName: (NSString*) aName {
if( name != aName ) {
if( name ) [name release];
name = [aName retain]; // or copy
}
}
or use properties right from the start.
Also, if you keep object references in instance variables, you should provide a proper definition of the dealloc
method:
- (void) dealloc {
self.name = nil;
[super dealloc];
}
Finally, just because an object has been deallocated, does not mean, that the memory of the former instance is invalidated. Your original program is most likely calling a method on a dangling reference (var
), which happens to work by sheer luck here. (In particular, to (auto
)release
does not automatically set the reference to nil
).
When you release the pointer var, you're telling the OS that the memory it pointed to is available to be reallocated. The pointer still points to that memory, and until it gets reallocated it still contains the remains of your object. Once it gets reallocated, trying to call the name method will no longer work.