Является ли расширение UIViewController для доступа к приложению делегатом антипаттерном? - PullRequest
0 голосов
/ 05 февраля 2019

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

Ответы [ 2 ]

0 голосов
/ 17 апреля 2019

Поместите эту функцию в файл AppDelegate, чтобы вы могли получить доступ к AppDelegate на протяжении всего проекта.

class func shared() -> AppDelegate {
     return UIApplication.shared.delegate as! AppDelegate
}

Вы можете использовать как:

AppDelegate.shared()
0 голосов
/ 05 февраля 2019

Если я расширил UIViewController, чтобы упростить доступ к делегату приложения, это в любом случае антипаттерн?

extension UIViewController {
    var appDelegate: AppDelegate {
        return UIApplication.shared.delegate as! AppDelegate
    } 
}

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


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

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

Но, допустим, вы чувствуете иначе.Тогда вы могли бы просто реализовать appDelegate явно в каждом соответствующем контроллере представления (за счет нарушения DRY).

Или (вот крутая часть) вы могли бы объявить протокол и расширение протокола и иметь толькосоответствующие контроллеры представления принимают это.Итак, вот ваш файл AppDelegate.swift :

import UIKit

protocol AppDelegateAccesser {}
extension AppDelegateAccesser {
    var appDelegate: AppDelegate {
        return UIApplication.shared.delegate as! AppDelegate
    }
}

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    // ....
}

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

extension MyViewController : AppDelegateAccesser {}

Это добавляет appDelegate в MyViewController, но не в другой класс.Таким образом, вы просто сделаете это для каждого контроллера представления, которому необходим доступ к делегату приложения, а не для других.Я думаю, что это совершенно ненужное упражнение, в отличие от вашего исходного предложенного решения, но оно действительно решает проблему внедрения кода только в некоторые классы.


ПРИМЕЧАНИЕ. В Swift 5 будет законно объявитьчто только подкласс UIViewController может принять этот протокол.Вам это может понравиться.

...