Person.h #import
@interface Person : NSObject {
NSString *name;
int age;
Person *spouse;
}
@property (nonatomic, retain) NSString* name;
@property int age;
@property (nonatomic, retain) Person *spouse;
- (id) initWithName:(NSString *)n age:(int)a;
- (id) initWithName:(NSString *)n age:(int)a spouse:(Person*)s;
@end
Person.m
@implementation Person
@synthesize name;
@synthesize age;
@synthesize spouse;
-(id) initWithName:(NSString *)n age:(int)a
{
return [self initWithName:n age:a spouse:nil];
}
-(id) initWithName:(NSString *)n age:(int)a spouse:(Person *)s
{
if((self = [super init]))
{
self.name = n;
self.age = a;
self.spouse = s;
}
return self;
}
-(NSString *)description
{
return [NSString stringWithFormat:@"name=%@, age=%d, spouse=%@", self.name, self.age, self.spouse.name];
}
- (void) dealloc
{
[name release];
[spouse release];
[super dealloc];
}
@end
然后我有这样的代码
Person *person1 = [[Person alloc] initWithName:@"Matt" age:33];
Person *person2 = [[Person alloc] initWithName:@"Clair" age:29 spouse:person1];
person1.spouse = person2;
NSLog(@"%@", person1);
NSLog(@"%@", person2);
NSLog(@"person1.retainCount=%d, person2.retainCount=%d", person1.retainCount, person2.retainCount);
[person2 release];
NSLog(@"person1.retainCount=%d, person2.retainCount=%d", person1.retainCount, person2.retainCount);
[person1 release];
NSLog(@"person1.retainCount=%d, person2.retainCount=%d", person1.retainCount, person2.retainCount);
最后,person1.retainCount = 1 person2.retainCount = 1,他们永远不会得到 - (无效)dealloc,所以当这种情况出现时,如何应对......
答案 0 :(得分:5)
你在这里称之为保留周期,它是引用计数内存管理方案的最大缺陷。这就是为什么不保留代表的约定。
你需要找到一种方法来打破这个循环(例如在释放一个人之前,将他们的配偶设置为零,可能是他们的配偶的配偶)或完全避免它。例如,您可以创建一个具有两个assign
属性的婚姻类,每个伙伴一个,而不是配偶属性,每个人都有一个指向婚姻对象的retain
婚姻属性。然后,当一个人被解除分配(现在将是)时,您将另一个伙伴的婚姻属性设置为nil。
所以你的界面看起来像这样:
@interface Person
// ...
@property (retain) Marriage* marriage;
@property (readonly, retain) Person* partner;
@end
@interface Marriage
/*
* DOES NOT RETAIN THE TWO PASSED IN PEOPLE
*/
-(id) initWithPartner: (Person*) aPerson andSpouse: (Person*) anotherPerson;
/*
* Returns the other person in the marriage or nil if the passed in person is not in
* this marriage
*/
-(Person*) partnerOf: (Person*) aPerson;
/*
* Removes a person from a marriage.
*/
-(void) removePartner: (Person*) aPerson;
@end
人的dealloc看起来像这样。
-(void) dealloc
{
Person* thePartner = [self partner];
/*
* Remove both partners from the marriage so that if something else has retained it, there will not be a problem
* with dangling pointers
*/
[[self marriage] removePartner: thePartner];
[[self marriage] removePartner: self];
[[self partner] setMarriage: nil]; // anulls the marriage
[self setMarriage: nil]; // Assuming only self and our partner owned the marriage, it will now be gone
[super dealloc];
}
因此实施了人的合伙人财产:
-(Person*) partner
{
return [[self marriage] partnerOf: self];
}
你也可以反过来这样做,以便婚姻拥有人民,而人民对婚姻的参照不足。