Objective-C: элегантное решение для условного создания объектов? - PullRequest
1 голос
/ 02 октября 2009

Это вопрос Objective-C / iphone SDK.

У меня есть панель инструментов, которая используется для переключения на другие виды в моем приложении. По сути, у представления есть шесть кнопок, которые ярлыки для другого вида.

Вот пример кода обработки события кнопки:

- (IBAction)moreButtonPressed:(id)sender{
 // switch view here
 if(self._moreViewController == nil){
  MoreViewController *moreViewController = [[MoreViewController alloc] initWithNibName:@"MoreView" bundle:[NSBundle mainBundle]];
  self._moreViewController = moreViewController;
  [moreViewController release];
 }

 [self SwitchView:self._moreViewController];
}

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

Кто-нибудь знает, как это сделать?

Ответы [ 2 ]

4 голосов
/ 02 октября 2009

Сначала переместите имя NIB в класс ViewController с помощью кода, такого как:

- (MoreViewController *)init
{
    self = [super initWithNibName:@"MoreView" bundle:nil];
    if (self != nil)
    {
    }
    return self;
}

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

MoreViewController *moreViewController = [[MoreViewController alloc] init];

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

Далее, помните, что ObjC - это динамический язык. Вы можете создавать объекты на основе их Class name следующим образом:

Class vcClass = NSClassFromString([self.classNameForSender objectForKey:sender])
UIViewController *vc = [[[vcClass alloc] init] autorelease];
[self switchToView:vc];

В приведенном выше примере -classNameForSender - это NSDictionary, который отображает объекты кнопки на имя класса, но вы, конечно, можете получить эти имена классов многими другими способами. В зависимости от отправителя, вы можете повесить класс непосредственно на отправителя (хотя это трудно сделать со стандартными UIControl s, потому что у них есть только целое число tag для работы).

Я не продублировал твое хранение ВК в иваре. Тебе это действительно нужно? Если это так, вы можете сохранить его в словаре по имени или вы можете сохранить все VC в NSMutableSet. Но в большинстве случаев вам это действительно не нужно, поскольку большинство контроллеров пользовательского интерфейса (например, NavController) будут управлять памятью за вас.

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

0 голосов
/ 02 октября 2009

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

- (IBAction)someButtonPressed:(id)sender{
 // switch view here

switch (sender.tag) {
case 0:
 if(self._moreViewController == nil){
  MoreViewController *moreViewController = [[MoreViewController alloc] initWithNibName:@"MoreView" bundle:[NSBundle mainBundle]];
  self._moreViewController = moreViewController;
  [moreViewController release];}
[self SwitchView:self._moreViewController];
break;
case 1:
 if(self._lessViewController == nil){
  MoreViewController *lessViewController = [[LessViewController alloc] initWithNibName:@"LessView" bundle:[NSBundle mainBundle]];
  self._lessViewController = lessViewController;
  [lessViewController release];}
[self SwitchView:self._lessViewController];
break;
 }

}

таким образом, у вас есть только одна функция. Однако было бы неплохо не повторять код в операторе case и просто предоставлять параметр класса для создания экземпляра. Хотя это не то, что я пробовал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...