Objective-C 自动释放池不释放对象

发布于 2024-08-31 15:52:54 字数 746 浏览 6 评论 0原文

我对 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;
}

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

汹涌人海 2024-09-07 15:52:54

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

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.

傲影 2024-09-07 15:52:54

您的代码有几个问题。首先,您既不复制也不保留存储在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)。

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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文