Search code examples
iosswiftcocoa-touchinitializationcomputer-science

Swift: Cannot use instance member 'trialGame' within property initializer; property initializers run before 'self' is available


In my Swift ViewController, I have the code

class ViewController: UIViewController {
    
    var camera: UIButton!
    
    var gameBrowser: UICollectionView!
    let gameBrowserReuseID = "gamecell"
    
    var games: [Game]!
    
    
    let trialGame = Game(id: "5", title: "Dog", release_date: "1989", publisher: "Nintendo", price: "20", platform: "OS X", category: "Adventure", players: ["A", "B"])
    let trialGame2 = Game(id: "5", title: "Dog", release_date: "1989", publisher: "Nintendo", price: "20", platform: "OS X", category: "Adventure", players: ["A", "B"])
    
    games = [trialGame, trialGame2]

However, on the last line, I'm getting the error "Cannot use instance member 'trialGame' within property initializer; property initializers run before 'self' is available" (and a second one for trialGame2). I searched this error on other forums, and it seems like this error is generally caused because one or more variables in the erroneous line of code are not available at the same time, but I'm not sure why this would be the case, because all I'm doing is declaring two objects of class Game as constants. Since they're both declared before I initialize array games, why aren't they both available?

Most posts recommend to use the keyword 'lazy' in front of the erroneous line of code, so: lazy var games = [trialGame, trialGame2] but for some reason the compiler is telling me that I need an initialization for keyword lazy. I'm not sure what this means, and the compiler's only recommendation is to remove the keyword.

If it helps, here is my Game class:

import UIKit

class Game: Codable {
    var id: String!
    var title: String!
    var release_date: String!
    var publisher: String!
    var price: String!
    var platform: String!
    
    var category: String!
    var players: [String]!
    
    init(id: String, title: String, release_date: String, publisher: String, price: String, platform: String, category: String, players: [String]){
        self.id = id
        self.title = title
        self.release_date = release_date
        self.publisher = publisher
        self.price = price
        self.platform = platform
        self.category = category
        self.players = players
    }
}

I'm feeling very lost here, since both the reason behind the error and the solution are eluding me. Grateful for any help!


Solution

  • First of all never, never ever declare properties as implicit unwrapped optionals which are initialized with non-optional values. Remove all exclamation marks!

    To answer your question you cannot run arbitrary code outside of a method in a class, why not simply

    class ViewController: UIViewController {
        
        var camera: UIButton!
        
        var gameBrowser: UICollectionView!
        let gameBrowserReuseID = "gamecell"
        
        var games = [Game(id: "5", title: "Dog", release_date: "1989", publisher: "Nintendo", price: "20", platform: "OS X", category: "Adventure", players: ["A", "B"]),
                     Game(id: "5", title: "Dog", release_date: "1989", publisher: "Nintendo", price: "20", platform: "OS X", category: "Adventure", players: ["A", "B"])]