Созданный Nib вид, сохраняющий владельца файла, предотвращает освобождение UIViewController - PullRequest
3 голосов
/ 12 октября 2011

У меня есть контроллер представления, который я хочу выпустить (а затем, возможно, перераспределить позже в приложении).Проблема в том, что его представление, похоже, содержит в себе сильную ссылку на него, как показано на трассировке стека ниже.Нужно ли освобождать представление перед контроллером представления?Если так, как я могу это сделать?Спасибо за помощь:)

Код:

- (void)setCurrentCourse:(Course *)newCourse
{
    ... Reference count management ...

    // area of concern
    if (currentCourse == nil) {

        [self.rvc.view removeFromSuperview];
        [self.rvc release];
        // HERE I want rvc to be deallocated, but the retainCount is one.
    } else {
        // This is where I allocate the rvc instance
        self.rvc = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:[NSBundle mainBundle] courseSelectionController:self];
        [self.view addSubview:self.rvc.view];
    }
}

Возвращение от переопределения - (id) сохранить;

#0  -[RootViewController retain] (self=0x1bb610, _cmd=0x349b6814) at RootViewController.m:609
#1  0x340b1cdc in CFRetain ()
#2  0x341620c0 in __CFBasicHashStandardRetainValue ()
#3  0x34163440 in __CFBasicHashAddValue ()
#4  0x340b1ff8 in CFBasicHashAddValue ()
#5  0x340b6162 in CFSetAddValue ()
#6  0x340c3012 in -[__NSCFSet addObject:] ()
#7  0x348cb70c in -[UINib instantiateWithOwner:options:] ()
#8  0x348cce08 in -[NSBundle(UINSBundleAdditions) loadNibNamed:owner:options:] ()
#9  0x348465e8 in -[UIViewController _loadViewFromNibNamed:bundle:] ()
#10 0x34813fa4 in -[UIViewController loadView] ()
#11 0x346f8ebe in -[UIViewController view] ()

Ответы [ 2 ]

1 голос
/ 12 октября 2011

Если rvc является сохраняемым свойством, у вас есть утечка .Вот почему контроллер не получает dealloc.Когда вы создаете контроллер представления, вы чрезмерно сохраняете it:

self.rvc = [[RootViewController alloc] initWithNibName:...];

alloc возвращает сохраненный объект (+1).Затем установщик свойств также сохраняет объект (+2).Позже, когда вы отпускаете (-1) объект, вы получаете + 1.

. Чтобы решить эту проблему, используйте временную переменную или autorelease:

self.rvc = [[[RootViewController alloc] initWithNibName:...] autorelease];

Еще одна проблема связана с тем, как вы освобождаете объект, который удерживает ваше свойство:

[self.rvc release];

После этого заявления вы отказались от права собственности на объект, и ничто не гарантирует, что объект будет действительнымбудущее, но ваша собственность все еще держит указатель на него.Другими словами, у вас есть потенциальная свисающая ссылка.Итак, обнуляйте свойство при его освобождении с помощью этого единственного оператора (это освободит старый объект):

self.rvc = nil;
1 голос
/ 12 октября 2011

Измените [self.rvc release]; на [rvc release];:

- (void)setCurrentCourse:(Course *)newCourse {
    // area of concern
    if (currentCourse == nil) {
        [self.rvc.view removeFromSuperview];
        [rvc release];
        // HERE I want rvc to be deallocated, but the retainCount is one.
    } else {
        // This is where I allocate the rvc instance
        rvc = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:[NSBundle mainBundle] courseSelectionController:self];
        [self.view addSubview:self.rvc.view];
    }
}

или используйте self.rvc = nil;, потому что когда вы устанавливаете nil в качестве переменной экземпляра, установщик просто сохраняет nil (который ничего не делает) и освобождает старыйзначение.

И используйте

rvc = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:[NSBundle mainBundle] courseSelectionController:self];

вместо

self.rvc = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:[NSBundle mainBundle] courseSelectionController:self];

...