2012-02-09 3 views
0

Я понимаю, что есть много вопросов, подобных этому, но, просмотрев их довольно много, мне все еще не хватает уверенности в том, правильно ли я делаю. Я прошу прощения, если этот вопрос лишний, однако я бы очень хотел пригвоздить то, что я делаю, это не плохая практика ...Управление памятью для программно созданного viewControllers

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

Во всяком случае, код выглядит следующим образом:

//Interface 
@interface ViewController : UIViewController 
{ 
    SettingsViewController *settingsViewController; 
} 
@property(retain, nonatomic) SettingsViewController *settingsViewController; 

А вот реализация:

//Implementation 
-(IBAction)changeSettings:(id)sender 
{ 
    if(!settingsViewController) 
    { 
     settingsViewController = [[SettingsViewController alloc] initWithNibName:@"SettingsViewController" bundle:nil]; 

     //Do some stuff here with CGRect to put the subview in the center of the view 

     [self.view addSubview:settingsViewController.view]; 
    } 
    else 
    { 
     [settingsViewController.view removeFromSuperview]; 
     [settingsViewController release]; 
     [self setSettingsViewController:nil]; 
    } 
} 

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

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

  • @property сохраняют на settingsViewController (сохранить это 1)
  • после Alloc на settingsViewController (сохранить это 2)
  • после addSubview: settingsViewcontroller.view (удержание равно 3)

Я думаю, что я здесь что-то не так. Вернее, я знаю, что это так, потому что он рушится.

Я действительно надеюсь, что это вопрос, который нужно задать. По сути, я хотел бы знать, как справиться с такой ситуацией. Я программно выделяю viewcontroller, а также делаю addSubiew, но я хотел бы сохранить ссылку на объект, так как мне это нужно в другом месте кода. Каким будет правильный способ справиться с этим?

спасибо !!

ответ

1

Проблема заключается в том, что вы слишком часто освобождаете settingsViewController.

if(!settingsViewController) 
{ 
    settingsViewController = [[SettingsViewController alloc] initWithNibName:@"SettingsViewController" bundle:nil]; 
    // [settingsViewController retainCount] should now equal 1 

    [self.view addSubview:settingsViewController.view]; 
} 
else 
{ 
    [settingsViewController.view removeFromSuperview]; 

    [settingsViewController release]; 
    // [settingsViewController retainCount] should now equal 0 

    [self setSettingsViewController:nil]; 
    // [settingsViewController retainCount] should now equal -1. This is most 
    // likely causing your crashes. 
} 

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

[settingsViewController release]; 
settingsViewController = nil 

или использование:

[self setSettingsViewController:nil]; 
+0

Спасибо! Однако у меня есть разъяснение, чтобы спросить: До этой строки: settingsViewController = [[SettingsViewController alloc] initWithNibName: @ "SettingsViewController" bundle: nil]; Из-за свойства @property (сохранение), не будет ли счет удержания уже 1? то, следуя вышеперечисленному значению, не будет ли счет удержания стать 2? – kurisukun

+0

В этом конкретном случае вы не вызываете свойство, когда вы выделяете и инициализируете settingsViewController. Если вы использовали строку 'self.settingsViewController = [[SettingsViewController alloc] initWithNibName: @" SettingsViewController "bundle: nil];' вы были бы правы, счет сохранения будет равен 2.Вы сохраняете свой контроллер, как если бы он был нормальным ivar при его распределении, но рассматривая его как ивара, так и свойство при его освобождении. –

+0

Спасибо! Я не понимал этого о self.settingsViewController. Если я могу спросить, что это правильный способ сделать что-то в этом случае? Должен ли я сделать это, как показано выше, или что-то совершенно другое? – kurisukun