2012-03-08 2 views
0

Я прочитал following tutorial относительно раскадровки.Xcode (раскадровки и segues): почему делегаты вместо ссылок?

В основном образец приложения, созданного в этом учебном пособии, позволяет пользователю перемещаться между различными видами и создается с помощью segue.

Для того, чтобы перемещаться между представлениями учебник сказать, чтобы создать два UITableViewController и когда «происходит» от одного к другому, чтобы указать делегата:

Первый контроллер:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
    if ([segue.identifier isEqualToString:@"AddPlayer"]) 
    { 
     UINavigationController *navigationController = segue.destinationViewController; 
     PlayerDetailsViewController *playerDetailsViewController = [[navigationController viewControllers] objectAtIndex:0]; 
     playerDetailsViewController.delegate = self; 
    } 
} 

Второй контроллер:

@protocol PlayerDetailsViewControllerDelegate <NSObject> 

- (void)playerDetailsViewControllerDidCancel: (PlayerDetailsViewController *)controller; 
- (void)playerDetailsViewController: (PlayerDetailsViewController *)controller didAddPlayer:(Player *)player; 

@end 

@interface PlayerDetailsViewController : UITableViewController 

@property (nonatomic, weak) id <PlayerDetailsViewControllerDelegate> delegate; 

Когда "вернуться":

- (IBAction)cancel:(id)sender 
{ 
    [self.delegate playerDetailsViewControllerDidCancel:self]; 
} 



Мой простой вопрос - почему это осложнение? Зачем использовать делегаты и протоколы?

Я изменил код, используя стиль «Java», и теперь я передаю второму контроллеру ссылку на первую, все работает.

Первый контроллер:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
... 
     playerDetailsViewController.playerViewController = self; 
} 

Второй контроллер:

@property (strong, readwrite) PlayerViewController *playerViewController; 

Итак, каковы преимущества для использования делегатов, а не просто проходящие ссылки между ViewControllers?

Спасибо!

Guido

ответ

0

Говоря таким образом, Java, если вы используете сильный тип вы привязаны к одному классу. Вместо этого делегат в конце соответствует классу, соответствующему протоколу. Итак, вы можете передать много классов в качестве делегатов в playerDetail, если они соответствуют @protocol.

Походит на литье и прохождение интерфейса вместо конкретного класса в java. Вы можете хорошо знать интерфейс List и все реалистичные реализации ArrayList, LinkedList ... и т.д.

Одна вещь, которую я не понимаю, - это то, почему они получают контроллер назначения, проходя через навигацию. Я всегда использовал:

MyDestinationViewController *dvc = [segue destinationViewController]; 

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

+0

Спасибо за ответ! –

1

Несколько причин:

  • As Leonardo says, используя ссылки Вы соединяете два контроллера просматривать вместе с ненужной. Вы должны просто передать данные, которые необходимы, а не весь класс
  • Это как раз то, как приложения Objective-C имеют тенденцию к построению.Используя другой метод, вы должны усложнять свое приложение при помощи опытных разработчиков.
  • (Вам не обязательно нужен делегат во втором классе - например, когда он отображается только на дисплее - поэтому ваш примерный код больше сложный, чем это часто бывает)

Связано с последней точкой, ваш код уже сложнее, чем нужно. UIStoryboardSegue имеет свойства, указывающие на контроллер источника и назначения; нет необходимости возиться с навигационным контроллером.

+0

Повторите последний пункт - если целевой VC встроен в контроллер навигации (в отличие от того, что он находится в пределах того же навигационного стека, что и текущий контроллер), тогда вам нужно все, что беспорядок – jrturton

+0

@jrturton Да, вы правы. Я неправильно прочитал код. Тем не менее, представленный код более сложный, чем самый распространенный случай (я думаю). –

+0

Спасибо за ответ! –

Смежные вопросы