How do I properly use class variables?

Suppose I have classes foo and bar:

Code Block
class foo {
}
class bar: foo {
}


I will never instantiate foo, but I will instantiate bar, and other foo subclasses. (foo will provide some functions for its subclasses to use and potentially override, so it's not something that could be replaced with a protocol, as I understand it.)

Now, suppose that I wanted to define a class variable in foo, that would be available to all subclasses, and I wanted to set the value of that variable at runtime, from outside foo and any of its subclasses. How do I do this? I've been wrestling with all kinds of different syntax and can't figure it out.

Or is there a better way to achieve the same goal in Swift that my brain hasn't grokked yet?

Replies

How do I do this? I've been wrestling with all kinds of different syntax and can't figure it out.

Can you show some of them? Frankly, I do not understand what you are trying to do, and expecting some codes would make it clearer.
Class names should start by uppercase.
define a class variable in foo
Do you mean a static var or just a property in class ?

Is this what you look for ? :

Code Block
class Foo {
static var staticValue: Int = 0
var value: Int = 0
}
class Bar: Foo {
convenience init(with initValue: Int) {
self.init()
self.value = initValue
}
}
print("Bar.staticValue", Bar.staticValue)
let bar = Bar(with: 3)
print("bar.value", bar.value)

You get:
Bar.staticValue 0
bar.value 3


Is this what you look for ?

Not quite, no... I want to be able to set the value from outside, not from within one of the child classes. Here's one of the examples I tried out in a playground, which actually "crashed" with an EXC_BAD_ACCESS error. 😬

The basic idea is that it's an object that will be available to all subclasses, but that is not known at compile time and must be set at runtime. I'm trying to avoid the use of a global variable, as that's a poor solution, but I'm starting to wonder if Swift supports the concept of these class variables in the same way that other languages I've used do.

Code Block
class foo {
    class var a: String {
        set { self.a = newValue }
        get { return self.a }
    }
}
class bar: foo {
    func printit() {
        print(foo.a)
    }
}
foo.a = "abc"
let someBar = bar()
someBar.printit()



 I'm trying to avoid the use of a global variable, as that's a poor solution,

Please do not forget, using too many class variable is as poor as, or poorer than using a global variable.

but I'm starting to wonder if Swift supports the concept of these class variables in the same way that other languages I've used do.

What sort of languages are you accustomed?


You can write something like this:
Code Block
class Foo {
private static var _a: String = ""
class var a: String {
set { self._a = newValue }
get { return self._a }
}
}
class Bar: Foo {
func printit() {
print(Foo.a)
}
}
Foo.a = "abc"
let someBar = Bar()
someBar.printit()

But not sure if this is what you want.
Thanks, I ended up finding a solution myself... it appears I was misunderstanding the way the static keyword works in Swift.

Here's what I ended up with (minus error checking that would go into the real code, of course):

Code Block
class foo {
    static var a: String?
    func printit() {
        print(foo.a)
    }
}
class bar: foo {
}
foo.a = "def"
let someBar = bar()
someBar.printit()


This does what I want. Your point about being cautious with these things is taken; not to worry, this isn't something I plan to do much of, but it does provide a cleaner solution to tie this to the class rather than making it a true global. 🙂

it appears I was misunderstanding the way the static keyword works in Swift.

I hope you have noticed that showing what you tried would give you the solution sooner.

it does provide a cleaner solution to tie this to the class rather than making it a true global.

It depends on how a is used. But in most cases it might be a clearer solution. Hoping yours would not be an exception.


By the way, in Swift you use Capitalized identifiers for types. You should better follow the basic coding rule of Swift if you continue coding in Swift.