JetForMe
(Rick M)
1
Arghh, this is always so annoying. What am I doing wrong?
Xcode (12b6, SPM, 5.3) says "Constant 'self.propertyDescriptors' used before being initialized" at the call to buildPropertyDecsriptors(). But I don't see it being used at all, just the attempt to assign it.
Other annoying things: I can't seem to let it default uninitialized optional properties to nil (I thought Swift used to do that?)
struct
MachineContent : Content
{
let id: UUID
let name: String
let imageURL: String?
let libraries: [LibraryContent]?
let propertyDescriptors: [UUID : PropertyDescriptorContent]?
init(id inID: UUID, name inName: String, imageURL inImageURL: String?, libraries inLibraries: [LibraryContent]? = nil)
{
self.id = inID
self.name = inName
self.imageURL = inImageURL
self.libraries = inLibraries
self.propertyDescriptors = nil
}
init(from inMachine: Machine, loadDescriptors inLoadDescriptors: Bool = true)
{
self.id = inMachine.id!
self.name = inMachine.name
self.imageURL = inMachine.imageURL
if inLoadDescriptors
{
self.libraries = inMachine.toolLibraries.map { LibraryContent(from: $0) }
self.propertyDescriptors = buildPropertyDecsriptors(machine: inMachine) // Error here
}
else
{
self.libraries = nil
self.propertyDescriptors = nil
}
}
func
buildPropertyDecsriptors(machine inMachine: Machine)
-> [UUID : PropertyDescriptorContent]?
{
// Get a unique set of PropertyDescriptors…
var descriptors = Set<PropertyDescriptor>()
inMachine.toolLibraries.forEach
{ (inLibrary) in
inLibrary.tools.forEach
{ (inTool) in
inTool.properties.forEach { descriptors.insert($0.descriptor) }
inTool.tool?.properties.forEach { descriptors.insert($0.descriptor) }
inTool.holder?.properties.forEach { descriptors.insert($0.descriptor) }
inTool.insert?.properties.forEach { descriptors.insert($0.descriptor) }
}
}
var descContent = [UUID : PropertyDescriptorContent]()
descriptors.forEach
{ (inDesc) in
descContent[inDesc.id!] = PropertyDescriptorContent(from: inDesc)
}
return descContent
}
}
Lantua
2
Instance methods use the entire self, and require self to be fully initialized.
2 Likes
JetForMe
(Rick M)
3
I wish there was a way around that. I ended up making the variables var.
JetForMe
(Rick M)
4
I'd also argue the error message is confusing.
Lantua
5
You could make the method (private) global function that takes only necessary arguments.
JetForMe
(Rick M)
6
Sure, or make it static, but ugh.
JetForMe
(Rick M)
7
Oh, no, that doesn't work. Why not?
Lantua
8
What does the code look like?
func add1(_ value: Int) -> Int {
value + 1
}
struct Foo {
let a, b: Int
init(a: Int) {
self.a = a + 1
b = add1(self.a)
}
}
JetForMe
(Rick M)
9
Why can't I do this?
struct Foo {
let a, b: Int
init(a: Int) {
self.a = a + 1
self.b = Self.add1(self.a)
}
static func add1(_ value: Int) -> Int {
value + 1
}
}
Lantua
10
You can? I don't get any error. Which version are you using?
JetForMe
(Rick M)
12
I added static to buildPropertyDecsriptors, and called it in init with Self. buildPropertyDecsriptors().
orobio
(Manolo van Ee)
13
That should work. What error do you get? You have misspelled decsriptors. Perhaps you haven’t in all places?
JetForMe
(Rick M)
14
My bad. That error does clear up when I make it static. The other errors (Return from initializer without initializing all stored properties) persist when I make the field let instead of var.
I thought Swift defaulted Optional types to nil.
Lantua
15
It only applies to Optional var. There's no default value for let of any type.
Somewhat of a quirk, and some even suggest making it consistent by removing default from Optional var.