2015-02-09 2 views
0

У меня есть код наблюдателя свойства, которое должно изменить IBOutlet свойства:Swift наблюдатель недвижимости и ноль

@IBOutlet weak var canYouGuessLbl: UILabel! 

var isNewUser: Bool = false { 
    didSet { 
     if isNewUser { 
      canYouGuessLbl!.layer.zPosition = 5 
      canYouGuessLbl!.hidden = false 
     } else { 
      canYouGuessLbl!.hidden = true // Error at this line 
     } 

    } 
} 

Это происходит сбой во время выполнения, потому что canYouGuessLbl! Кажется, что ноль:

fatal error: unexpectedly found nil while unwrapping an Optional value 

Я не уверен в причине и как решить эту проблему.

ответ

0

Спасибо за ваши отвечает ребятам. Это вдохновило меня для этого решения:

мне пришлось поместить действие выполнить в отдельной функции:

func ifNewUser() { 
    if isNewUser! { 
     canYouGuessLbl?.layer.zPosition = 5 
     canYouGuessLbl?.hidden = false 
    } else if !isNewUser! { 
     canYouGuessLbl?.layer.zPosition = 5 
     canYouGuessLbl?.hideAndDisable() 
    } 
} 

Основная проблема была с инициализацией, поэтому сначала я проверить это в viewDidLoad:

ifNewUser() 

Поскольку значение bool получает свое значение очень рано с помощью segue, его сначала следует проверить сначала в viewDidLoad после того, как все переменные, включая IBoutlets, инициализируются.

Затем, когда пользователь не объявлен новый пользователь больше, я держать наблюдателя, но при вызове функции:

var isNewUser: Bool? { 
    didSet { 
     ifNewUser() 
     } 
    } 

ли работу.

1

Есть несколько причин, почему canYouGuessLbl может быть нулевым при назначении нового значения isNewUser:

  • isNewUser присваивается новое значение перед canYouGuessLbl инициализирован (до viewDidLoad, например, в инициализаторе)

  • выход не был определен для canYouGuessLbl (т.е. управление этикетки в интерфейсе строитель не был подключен к собственности)

  • контроллер вид в IB не подключен к классу реализации (пользовательский класс в инспекторе идентичности)

Update - В первом случае, вы можете исправить, явно проверяя не ноль:

var isNewUser: Bool = false { 
    didSet { 
     if canYouGuessLbl != nil { 
      if isNewUser { 
       canYouGuessLbl.layer.zPosition = 5 
       canYouGuessLbl.hidden = false 
      } else { 
       canYouGuessLbl.hidden = true // Error at this line 
      } 
     } 
    } 
} 

Обратите внимание, что при этом метка не будет обновляться (поскольку она еще не существует). Это просто предотвращает исключение.

didSet (и, в целом, наблюдатели свойств) не вызывается, когда свойство инициализировано.

+0

Это определенно 1.Итак, есть ли вообще что-нибудь наблюдать за NewUser после инициализации iboutlet? –

+0

Или, может быть, просто поставить: canYouGuessLbl? .Hidden = true и оператор if в функции, с? вместо!, вызовите его один раз в viewDidLoad для инициализации представления и оставьте наблюдателя выполнять работу над другими случаями. что может сделать трюк. Не уверен, что это лучший способ. –

+0

@RobertBrax: см. Обновленный ответ – Antonio

1

Если возникает проблема в ряде сценариев один из ответа Антонио, то вы можете решить, объявив переменную isNewUser в качестве факультативных и присвоить ей значение по методе viewDidLoad после canYouGuessLbl полностью инициализировано

var isNewUser: Bool! { 

    didSet(newValue) { 

     if isNewUser != nil && isNewUser! { 

      canYouGuessLbl!.layer.zPosition = 5 
      canYouGuessLbl!.hidden = false 

     } else if isNewUser != nil && !isNewUser! { 

      canYouGuessLbl!.hidden = true 

     } 

    } 
} 

override func viewDidLoad() { 
    super.viewDidLoad() 
    isNewUser = false 
} 
+0

@zelib: наблюдатели свойств не вызываются во время инициализации, поэтому нет причин сделать это необязательным. – Antonio

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