1

当两个对象相互保留时,如何绕过交叉保留情况?

考虑这个类结构:

容器.h

@interface Container : NSObject {
    NSObject *child;
}

@property (nonatomic, retain) NSObject *child;
@end

容器.m

@implementation Container

@synthesize child;

- (void)dealloc {
    [child release];
    [super dealloc];
}

@end

然后在测试内存保留计数时:

- (void)testDoubleRetain {
    Container *A = [[Container alloc] init];
    Container *B = [[Container alloc] init];

    NSLog(@"A retainCount: %d", [A retainCount]);//returns 1
    NSLog(@"B retainCount: %d", [B retainCount]);//returns 1
    [A setChild:B];
    [B setChild:A];

    NSLog(@"A retainCount: %d", [A retainCount]);//returns 2
    NSLog(@"B retainCount: %d", [B retainCount]);//returns 2

    [A release];
    [B release];

    NSLog(@"A retainCount: %d", [A retainCount]);//returns 1
    NSLog(@"B retainCount: %d", [B retainCount]);//returns 1
}

因此,据我了解,保留计数应该显示正确的计数。但是我最终如何真正解除分配对象,因为在这段代码之后,这两个对象将留在内存中。

4

2 回答 2

2

简单的解决方法可能是在释放对象本身之前将孩子归零:

A.child = nil;
[A release];

但是为了避免您的问题,可能值得重新考虑您的一般程序结构,这样您就不需要让 2 个对象相互保留(可能是它们的关系允许使用“分配”属性而不是“保留”,您可以确保它们不会通过其他方式过早地释放 - 例如,将它们全部放入某个全局容器中 - 这一切都取决于您的实际上下文)

于 2011-05-06T14:32:31.347 回答
1

首先,不要使用 retainCount。它不会像你想的那样做。

这里的正常做法是让孩子或容器保留另一个,这将打破循环。如果这不可能,请提供一个必须显式调用的函数,以告诉容器您已完成它,此时它将释放子容器。

于 2011-05-06T14:33:59.847 回答