-1

I'm trying to follow along CS 193P course and I'm currently on a Lecture 2. The lector made var game = Concentration(numberOfPairsOfCards: cardButtons.count / 2) and it worked fine for him, however, it doesn't work at all for me. Am I missing something? I can't pass anything there.

Here's my ViewController class:

class ViewController: UIViewController {

    @IBOutlet weak var flipCountLabel: UILabel!
    @IBOutlet var cardButtons: [UIButton]!

    var game = Concentration(numberOfPairsOfCards: cardButtons.count / 2)

    var emojiChoices = ["", "", "", ""]

    var flipCount = 0 {
        didSet {
            flipCountLabel.text = "Flips: \(flipCount)"
        }
    }

    //MARK: - IBActions
    @IBAction func touchCard(_ sender: UIButton) {
        flipCount += 1
        if let cardNumber = cardButtons.index(of: sender) {
            flipCard(withEmoji: emojiChoices[cardNumber], on: sender)
        }
    }


    //MARK: - Methods
    func flipCard(withEmoji emoji: String, on button: UIButton) {
        if button.currentTitle == emoji {
            button.setTitle("", for: .normal)
            button.backgroundColor = #colorLiteral(red: 0.9372549057, green: 0.3490196168, blue: 0.1921568662, alpha: 1)
        } else {
            button.setTitle(emoji, for: .normal)
            button.backgroundColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
        }
    }

}

And Concentration:

class Concentration {
    var cards = [Card]()

    func chooseCard(at index: Int) {

    }

    init(numberOfPairsOfCards: Int) {
        for _ in 1...numberOfPairsOfCards {
            let card = Card()
            cards += [card, card]
        }
        //TODO: - Shuffle the cards

    }


}

The error is

Cannot use instance member 'cardButtons' within property initializer; property initializers run before 'self' is available

and auto completion doesn't work either

user28434'mstep
  • 6,290
  • 2
  • 20
  • 35
Appolonia
  • 7
  • 1
  • Starting at 40:30 in the video, the prof explains you need to make it `lazy`. – vacawama Jul 23 '19 at 16:13
  • The prof intentionally makes common mistakes so that he can explain to you how to reason about them, what they mean, and how to fix them. You need to keep watching to make sure that isn't the case. – vacawama Jul 23 '19 at 16:25

1 Answers1

1

You need to make it a var

 var game:Concentration!

then inside viewDidLoad

game = Concentration(numberOfPairsOfCards: cardButtons.count / 2)

OR make it a lazy var

lazy var game:Concentration = {
   return Concentration(numberOfPairsOfCards:self.cardButtons.count / 2)
}()
Shehata Gamal
  • 98,760
  • 8
  • 65
  • 87
  • lazy var game: Concentration = { return Concentration(numberOfPairsOfCards:self.cardButtons.count / 2) }() This seems to work, so there were some syntax changes and this is a reason why it doesn't work anymore? – Appolonia Jul 23 '19 at 14:52
  • yes the line you wrote won't compile – Shehata Gamal Jul 23 '19 at 14:53
  • 1
    @Appolonia The explanation behind is that the cardButtons are not available before the object initialised and thus cannot be used to initialise another object. Once they are initialise (which this solution does) you can use it. (Lazy var lazily initialises the game property) – Ankit Srivastava Jul 23 '19 at 14:59
  • Just adding `lazy` is sufficient. You don't need to turn the creation of `Concentration` into a closure that is then called. That's what the prof did in the video if the OP had just kept watching. – vacawama Jul 23 '19 at 16:21
  • @vacawama it's is a habit origin from the fact that we always init a multiline object such as creating a lazy var to a tableView – Shehata Gamal Jul 23 '19 at 16:25