Xcode (раскадровки и сегы): почему делегаты вместо ссылок? - PullRequest
0 голосов
/ 08 марта 2012

Я прочитал следующий урок относительно раскадровки.

В основном образец приложения, созданный в этом руководстве, позволяет пользователю перемещаться между различными представлениями, и он создается с помощью 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

Ответы [ 2 ]

1 голос
/ 08 марта 2012

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

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

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

0 голосов
/ 08 марта 2012

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

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

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

MyDestinationViewController *dvc = [segue destinationViewController];

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

...