2016-05-06 2 views
0

Я столкнулся с ситуацией, когда хочу зарегистрировать 2 разных UIViewControllers с одним делегатом, потому что в моем проекте показывается 2 UIViewControllers за раз. Когда я запускаю событие, я хочу, чтобы оба контроллера получили уведомление, но, к сожалению, только один контроллер может получить событие не для обоих.Одиночный делегат с несколькими контроллерами

Вот пример кода:

@objc protocol DownloaderDelegate: class { 
    func complete() 
} 

class Downloader { 
    static let sharedInstance = Downloader() 
    weak var delegate: DownloaderDelegate? 

    private init() { 

    } 

    func downloadFile() { 
     self.delegate!.complete() 
    } 
} 

Я затем использовать его, как это в обоих UIViewControllers:

override viewDidLoad() { 
    super.viewDidLoad() 

    Downloader.sharedInstance.delegate = self 
} 

Любая идея, как сделать оба контроллера просмотра для прослушивания события из одного делегата ?

ответ

5

На самом деле, я считаю, что лучшим решением здесь будет переход от шаблона делегата к шаблону уведомления (более подробная информация о документации Apple: https://developer.apple.com/library/ios/documentation/General/Conceptual/DevPedia-CocoaCore/Notification.html).

Другим решением будет замена вашего делегата на массив DownloaderDelegate. Но я действительно считаю, что решение «Уведомления» является самым чистым и простым.

Вот хорошая статья на NSNotification в Swift: https://www.andrewcbancroft.com/2014/10/08/fundamentals-of-nsnotificationcenter-in-swift/

Edit: Вы должны позаботиться о снятии наблюдателей. Самый простой способ сделать это, чтобы добавить это в каждом классе прослушивания для событий:

deinit { 
     NSNotificationCenter.defaultCenter().removeObserver(self) 
} 
+0

Спасибо за предложение. Как насчет использования «обратных вызовов»? Потому что эта NSNotification также требует особой заботы об удалении наблюдателя. – codelearner

+0

«обратные вызовы» могут быть решением, но я думаю, что он менее прост, чем «NSNotification». При удалении наблюдателей вам просто нужно: 'NSNotificationCenter.defaultCenter(). RemoveObserver (self)' в методе 'deinit'. –

+0

Учитывая, что вы делаете загрузку, уведомления могут быть вашим лучшим вариантом, учитывая, что в какой-то момент вы можете иметь больше вещей, которые захотят узнать о завершении загрузки. – PeejWeej

1

Это единственный атрибут, поэтому существует только одна вещь. У вас есть множество вариантов, когда несколько VC реагируют на что-то. Вы можете иметь массив делегатов, подписываться и отправлять уведомления, иметь контейнер VC, который управляет двумя другими VC или многими другими подходами.

+0

Вы говорите, что экземпляр может выступать в качестве делегата только для одного объекта в данный момент времени? – harshitgupta

+0

Спасибо за предложение. Как насчет использования «обратных вызовов»? – codelearner

+0

@harshitgupta «delegate» - это атрибут класса, как и любой другой атрибут. У вас может быть только один за раз, как будто у вас может быть только один из атрибутов. – PeejWeej

0

Нет, его не представляется возможным. Подумайте об этом так. Класс downloader имеет свойство «делегат». Свойство может содержать только ссылку на один экземпляр за раз. Следовательно, он будет вызывать только методы экземпляра, «делегат», ссылающийся на (последнее присвоенное значение).

Как сказал @Onejjy, уведомления были бы хорошим способом его достижения.

Но если вы хотите использовать только шаблон делегата. Я бы сказал, поместив два свойства в загрузчик clss (свойства делегата) и соответствующим образом присвоить им. Затем продублируйте код «вызывающего метода делегата» везде, где это необходимо.

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