Крест сохраняет неприятности - PullRequest
1 голос
/ 06 мая 2011

Как вы справляетесь с ситуацией, когда два объекта удерживают друг друга?

рассмотрим структуру этого класса:

Container.h

@interface Container : NSObject {
    NSObject *child;
}

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

Container.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
}

Итак, насколько я понимаю, счет удержания должен был показывать правильный счет. но как мне в действительности освободить объекты, так как после этого блока кода эти два объекта останутся в памяти.

Ответы [ 2 ]

2 голосов
/ 06 мая 2011

Простой обходной путь может заключаться в том, чтобы обнулить ребенка перед выпуском самого объекта:

A.child = nil;
[A release];

Но, чтобы избежать вашей проблемы, возможно, стоит переосмыслить общую структуру программы, поэтому вам не нужно иметь 2 объектавзаимно сохранять друг друга (возможно, их отношения позволяют использовать свойство 'assign' вместо 'retain', и вы можете быть уверены, что они не будут преждевременно освобождены другими средствами - например, поместив их все в некоторый глобальный контейнер), чтобы всебудет зависеть от вашего фактического контекста)

1 голос
/ 06 мая 2011

Во-первых, не используйте retainCount .Он не делает то, что вы думаете.

Нормальная вещь, которую нужно сделать здесь, это иметь либо дочерний элемент, либо контейнер , а не , удерживать другого, что нарушит цикл.Если это невозможно, предоставьте функцию, которая должна явно вызываться, чтобы сообщить контейнеру, что вы сделали с ним, и в этот момент он освободит дочерний элемент.

...