3

我对 Objective-C 非常陌生,并且正在阅读内存管理。我试图玩弄 NSAutoreleasePool 但不知何故它不会释放我的对象。

我有一个带有 setter 和 getter 的类,它基本上设置了一个 NSString *name。释放池后,我尝试 NSLog 对象,它仍然有效,但我想它不应该?

@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;
}
4

2 回答 2

5

当您释放指针 var 时,您是在告诉操作系统它指向的内存可以重新分配。指针仍然指向该内存,并且在重新分配之前它仍然包含对象的剩余部分。一旦它被重新分配,尝试调用 name 方法将不再有效。

于 2010-05-07T12:42:08.007 回答
2

您的代码有几个问题。首先,您既不执行copy也不retain执行将字符串存储到name实例变量中。因此,如果字符串被存储到属性中的任何人释放,您将留下一个悬空引用。你应该做

- (void) setName: (NSString*) aName {
    if( name != aName ) {
        if( name ) [name release];
        name = [aName retain];    // or copy
    }
}

或从一开始就使用属性。

此外,如果您在实例变量中保留对象引用,您应该提供该dealloc方法的正确定义:

- (void) dealloc {
    self.name = nil;
    [super dealloc];
}

最后,仅仅因为一个对象已被释放,并不意味着前一个实例的内存无效。您的原始程序很可能在悬空引用 ( var) 上调用一个方法,这完全靠运气在这里工作。(特别是, to ( auto)release不会自动设置对 的引用nil)。

于 2010-05-07T12:44:28.507 回答