What does "cannot use instance member within property initializer" mean and how can I correct it in my code?"

import UIKit

import CoreData

//import Foundation

// @objc(Decisions)


class ViewController: UIViewController, UITableViewDelegate, UIApplicationDelegate {

init(){

}


required init?(coder aDecoder: NSCoder) {

fatalError("init(coder:) has not been implemented")

}


var decisions = [String]()


// var Gains: (() -> Void)!



var gain1 = ""

var gain2 = ""

var gain3 = ""

var gain4 = ""



let Gains = [gain1, gain2, gain3, gain4] ["cannot use instance member within property initializer". Without this line the "forEach" doesn't work.


override func viewDidLoad() {

super.viewDidLoad()

let persistentContainer = NSPersistentContainer(name: "No_Regrets")

persistentContainer.loadPersistentStores { (_, error) in

if let error = error {

fatalError("Failed to load Core Data stack: \(error)")

}

}

// Creates a task with a new background context created on the fly

persistentContainer.performBackgroundTask { (context) in

// Iterates the array

Gains.forEach { name in

// Creates a new entry inside the context `context` and assign the array element `name` to the dog's name

let gain1 = Gains(context: context)

gain1.name = name

let gain2 = Gains(context: context)

gain2.name = name

let gain3 = Gains(context: context)

gain3.name = name

let gain4 = Gains(context: context)

gain4.name = name

}

do {

// Saves the entries created in the `forEach`

try context.save()

} catch {

fatalError("Failure to save context: \(error)")

}

}

Accepted Reply

The error message is correct. You cannot use (for example) "gain1" to initialize the value of "Gains". That's a circular definition, though it may not immediately be obvious why. The definition is essentially:


    let Gains = [self.gain1, self.gain2, self.gain3, self.gain4]


But this is a property of "self", and the "self" object isn't fully created until "Gains" is initialized. That's the circularity: "Gains" depends on "self", and "self" depends on "Gains".


One alternative is to use a computed property:


    var Gains: [String] { return [self.gain1, self.gain2, self.gain3, self.gain4] }


Another is to use an implicitly unwrapped optional:


    var Gains: [String]!


then inside "viewDidLoad":


     Gains = [gain1, gain2, gain3, gain4]

Replies

The error message is correct. You cannot use (for example) "gain1" to initialize the value of "Gains". That's a circular definition, though it may not immediately be obvious why. The definition is essentially:


    let Gains = [self.gain1, self.gain2, self.gain3, self.gain4]


But this is a property of "self", and the "self" object isn't fully created until "Gains" is initialized. That's the circularity: "Gains" depends on "self", and "self" depends on "Gains".


One alternative is to use a computed property:


    var Gains: [String] { return [self.gain1, self.gain2, self.gain3, self.gain4] }


Another is to use an implicitly unwrapped optional:


    var Gains: [String]!


then inside "viewDidLoad":


     Gains = [gain1, gain2, gain3, gain4]

Thank You Very Much Quincy. I am new to Xcode and Swift and that levely of analysis is beyoud my knowledge level. Thanks for your help.