Необязательный IBOutlet возвращает фатальную ошибку: при ссылке из другого класса UIViewController - PullRequest
0 голосов
/ 20 декабря 2018

У меня UIView определен в

class InteractViewController: UIViewController {

    @IBOutlet weak var tipsView: UIView!
        var tipslayer: CALayer {
        return tipsView.layer
    }
}

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

@IBOutlet weak var tips1Top: NSLayoutConstraint!
@IBOutlet weak var tips1Right: NSLayoutConstraint!
@IBOutlet weak var tipsTitle: UILabel!
@IBOutlet weak var tipsDesc: UILabel!

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

Тем не менее, они не нужны, если пользователь впервые не использует приложение, поэтому просто, если еще вызовы InteractViewControllerфункция, которая отображает и обновляет их свойства или не отображает их вообще.

Функция, которая управляет и обновляет эти свойства, находится в другом классе (файл Swift в проекте называется.

class TipsViewController: UIViewController {

    func tips() {
        InteractViewController().tipslayer.transform = CATransform3DMakeScale(0.8, 0.8, 1.0)
    }
}

Вызывает сбой приложения при создании

Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

на

return tipsView.layer (the InteractViewController)

tipsView и tipslayer являются причинами, а не дополнительными и не объявляются как дополнительные.

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

  1. Имеет ли физическая ссылка на выходы в классе ViewController InteractViewController: UIViewController проблема? Если это так, потому что они должны бытьвместо этого программно добавлен класс TipsViewController: UIViewConТроллер (который не имеет физического контроллера визуального представления в XCode)?

  2. Имеет ли физическая ссылка на выходы класса

    InteractViewController: UIViewController

создает ненужное использование памяти, если в InteractViewController никогда не вызывается вызов функции во втором ViewContoller TipsViewController.tips (), поэтому, другими словами, ответом на вопрос 1, по сути, являются любые физические выходы, которые должны быть программнодобавлен в Lips TipsViewController: UIViewController?

Если нет проблем с памятью, и зная, что tipsView и возвращаемый слой подсказок не являются дополнительными, почему я просто не могу ссылаться на них из функции tips () в другом классе (TipsViewController: UIViewController)?Я видел несколько сообщений о «передаче данных между контроллерами представления», но я не передаю данные между переменными или массивами.Я хочу / нужно просто обновить строку метки, ограничения (объекты в одном классе контроллера представления из другого класса контроллера представления.

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

Было высказано предположение, что мой вопрос был дубликатом [ Что означает "фатальная ошибка: неожиданно обнаружен ноль при развертывании необязательного значения"?

Но это не мой вопрос. Мой вопрос касается конкретно доступа к Outlet из другого ViewController, который затем генерирует нулевой ответ на Outlet, потому что, как объяснено, InteractViewController, по-видимому, не ссылается на ViewController. Пожалуйста, прочтите объяснения и ответы, предоставленные Робом, который отвечаетэтот конкретный вопрос.

1 Ответ

0 голосов
/ 20 декабря 2018

Ваш заголовок гласит: «IBOutlet возвращает фатальную ошибку: при ссылке из другого класса UIViewController».Суть в том, что один контроллер представления никогда не должен обращаться к выходам другого контроллера представления.

В вашем фрагменте кода вы используете синтаксис InteractViewController().К сожалению, это просто создает экземпляр контроллера представления, но не подключает розетки в раскадровке.Вам нужно создать экземпляр через раскадровку, и даже тогда вы не можете сразу ссылаться на свои розетки, но только после того, как viewDidLoad будет вызван позже.В любом случае, только сам контроллер представления должен пытаться получить доступ к своим собственным выходам.

Синтаксис TipsViewController() или InteractViewController() гласит «создать новый пустой экземпляр этого контроллера представления».Это эквивалентно высказыванию TipsViewController.init() или InteractViewController.init().И, что еще хуже, он вообще не использует раскадровку (и поэтому никакие розетки не будут подключены).Это не то, что вы хотите.Вам следует избегать использования этого синтаксиса ViewController(), поскольку торговые точки никогда не будут доступны таким образом.


InteractViewController должен определять, следует ли представлять TipsViewController (например, проверять пользовательские настройки по умолчанию), и если да, то, представь это.Единственное, что InteractViewController должен сделать, однако, это:

  • выяснить, представить ли TipsViewController;
  • , если да, представить, что TipsViewController
  • передать данные модели (например, все, что InteractViewController извлечено из UserDefaults) в экземпляр TipsViewController, который создан для вас.

Но все, что угодно о том, как TipsViewController представляет свои подпредставления, является компетенцией только TipsViewController.InteractViewController никогда не должен взаимодействовать напрямую с какими-либо точками TipsViewController.

...