Swift - 初始化UIViewController

时间:2014-08-22 07:21:07

标签: ios swift

我在UIViewController中遇到了init参数的问题。我上课了:

class ViewController: UIViewController {
   @IBOutlet var cardButtons: Array<UIButton>

   var flipCount = 0
   var game: CardMatchingGame
   var backCardImage: UIImage
   var frontCardImage: UIImage

   required init(coder aDecoder: NSCoder) {
      self.backCardImage = UIImage(named: "back")
      self.frontCardImage = UIImage(named: "front")
      self.game = CardMatchingGame(count: cardButtons.count, deck: createDeck())

      super.init(coder: aDecoder)
  }

  @IBAction func touchCardButton(sender: UIButton) {
      var cardButtonsArray = cardButtons as NSArray
      var chosenButtonIndex = cardButtonsArray.indexOfObject(sender)
      game.chooseCardAtIndex(chosenButtonIndex)
  }

  func createDeck() -> Deck {
      return PlayingCardDeck()
  }

}

但我在

中遇到了错误
count: cardButtons.count >> Variable 'self.cardButtons' used before being initialized/Property 'self.cardButtons' not initialized at super.init call

deck: createDeck() >> 'self' used before super.init call

如何解决这个问题才能正确初始化UIViewController?

感谢您的帮助。

4 个答案:

答案 0 :(得分:3)

您希望覆盖awakeFromNib并访问其中的插座,而不是初始化设备。

“nib-loading基础结构向从nib存档重新创建的每个对象发送一个awakeFromNib消息,但只有在存档中的所有对象都已加载并初始化之后。当一个对象收到一个awakeFromNib消息时,它保证有所有的出口和行动联系已经确立。“

所以我建议像:

class ViewController: UIViewController {
   @IBOutlet var cardButtons: Array<UIButton>!

   var flipCount = 0
   var game: CardMatchingGame!
   var backCardImage: UIImage
   var frontCardImage: UIImage

   required init(coder aDecoder: NSCoder) {
      self.backCardImage = UIImage(named: "back")
      self.frontCardImage = UIImage(named: "front")

      super.init(coder: aDecoder)
  }

  override func awakeFromNib() {
      super.awakeFromNib()
      self.game = CardMatchingGame(count: cardButtons.count, deck: createDeck())
  }

  @IBAction func touchCardButton(sender: UIButton) {
      var cardButtonsArray = cardButtons as NSArray
      var chosenButtonIndex = cardButtonsArray.indexOfObject(sender)
      game.chooseCardAtIndex(chosenButtonIndex)
  }

  func createDeck() -> Deck {
      return PlayingCardDeck()
  }
}

答案 1 :(得分:0)

插座集合中的插座不会完全可用,直到包含它们的视图加载完毕。一旦视图完全加载到内存中,将调用视图控制器的viewDidLoad()函数。此时,应该可以使用对诸如插座集合之类的视图的引用。

所以,它看起来像这样:

override func viewDidLoad()
{
    super.viewDidLoad()
    self.game = CardMatchingGame(count: cardButtons.count, deck: createDeck())
}

Apple开发者网站viewDidLoad()的详细信息:viewDidLoad

答案 2 :(得分:0)

您只需将方法设为静态:

static func createDeck() -> Deck {
    return PlayingCardDeck()
}

并像这样使用它:

required init(coder aDecoder: NSCoder) {
    self.backCardImage = UIImage(named: "back")
    self.frontCardImage = UIImage(named: "front")
    self.game = CardMatchingGame(count: cardButtons.count, deck: ViewController.createDeck())

    super.init(coder: aDecoder)
}

答案 3 :(得分:-1)

如此处所述,所有变量都应在调用super.init之前初始化。

由于Interface Builder初始化@IBOutlet,感叹号应该没问题:

  

@IBOutlet var cardButtons:Array!

您可能还需要添加stronghttps://stackoverflow.com/a/24686602/3186336