NEW: Learn to build amazing SwiftUI apps for macOS with my new book! >>

SOLVED: Question: are all Static properties and methods will by default exist in all instances

Forums > 100 Days of SwiftUI

Hi ,

I understand that in Struct, @Static properties and methods belongs to the Struct , and when calling or accessing them, it is from a Struct level, not instance level. https://www.hackingwithswift.com/quick-start/beginners/static-properties-and-methods

Does that mean , by default, all the instances created from this Struct will have these static properties/methods (without initializer).

Because I imagine: if I change @static propoerties from a Struct level, it will automatically that property across all instances from that Struct.

In Paul's code it is like this:

struct School {
    static var studentCount = 0

    static func add(student: String) {
        print("\(student) joined the school.")
        studentCount += 1
    }
}

School.add(student: "Taylor Swift")

I guess, by default, from this moment on, all instances created from this Struct will naturally have "Taylor Swift " in their property , and the stuentCount will by be 1 already. ?

Boat

1      

I guess, by default, from this moment on, all instances created from this Struct will naturally have "Taylor Swift " in their property , and the stuentCount will by be 1 already. ?

Nope. Static properties belong to the type, not any particular instance of that type.

So, you can do this:

School.add(student: "Taylor Swift")

But you can't do this:

let school = School()
school.add(student: "Taylor Swift") 
  //Error: Static member 'add' cannot be used on instance of type 'School'
print(school.studentCount) 
  //Error: Static member 'studentCount' cannot be used on instance of type 'School'

In those examples, School (which is a type) has a property studentCount and a method add(student:) but school (which is an instance of the School type) does not.

Note that this is one reason why following the Swift convention of naming types with uppercase (e.g., School) and variables with lowercase (e.g., school) is such a good idea; it helps us tell what we're working with and what properties and methods are available when we read source code.

2      

@roosterboy, thank you .

But what is the point of having properties and methods accessing to the type (Struct) only without any impact on its instances ?

I mean, a Struct is not of any use if there is no instance created from it, right ?

1      

I think the usefulness is being able to keep information organised together in one thing (Struct in this case). You can keep both instance information (non-static properties and methods) and "global" information (static properties and methods) that pertain to the same concept (e.g. a Student or an Employee or a Car, etc.) in the same, single, place.

Also, remember that you can access the static information from the non-static properties and methods.

I like the idea of having instances keep track of individual data and using static properties/methods to accumulate statistics about all instances. Seems like a nice way to organise things.

2      

You can still access those static properties and methods inside a struct instance, but they don't belong to the instance.

Paul's example perhaps isn't the best example to demonstrate, but you can do stuff like this:

struct School {
    //shared by all School instances
    static var totalStudentsInDistrict = 0

    //local to each instance
    private var students: [String] = []
    var studentCount: Int { students.count }

    mutating func add(student: String) {
        //append to the local instance variable
        students.append(student)

        //note we use School here because this is
        //a static property
        School.totalStudentsInDistrict += 1
    }
}

var school1 = School()
school1.add(student: "Charlotte Grote")
print("school1 has \(school1.studentCount) student(s)")
  //school1 has 1 student(s)
print("there are \(School.totalStudentsInDistrict) student(s) in the district")
  //there are 1 student(s) in the district

var school2 = School()
school2.add(student: "Shauna Wickle")
print("school2 has \(school2.studentCount) student(s)")
  //school2 has 1 student(s)
print("there are \(School.totalStudentsInDistrict) student(s) in the district")
  //there are 2 student(s) in the district

So individual instances of School don't have their own totalStudentsInDistrict property, but all instance of School have access to the shared totalStudentsInDistrict property throught their type.

Static properties can also be useful when you have something like a DateFormatter that is expensive to create and all instances of the struct type will use the same formatter, so you don't want to make each instance carry its own.

struct Post {
    //shared by all Post instances
    static let dateFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateStyle = .full
        return formatter
    }()

    //local to each instance
    let published: Date
    let title: String
    let content: String
    var postedDate: String {
        //this uses the shared dateFormatter property
        //to format the instance published property
        Post.dateFormatter.string(from: published)
    }
}

let post1 = Post(published: Date(timeIntervalSinceNow: -86400), title: "A few thoughts", content: "...")
print(post1.postedDate)
  //Wednesday, December 29, 2021
let post2 = Post(published: .now, title: "A follow up to yesterday's post", content: "...")
print(post2.postedDate)
  //Thursday, December 30, 2021

So individual instances of Post don't have their own dateFormatter property, but all instances of Post have access to the shared dateFormatter property throught their type.

2      

@ty-n-42, well said on "the idea of having instances keep track of individual data and using static properties/methods to accumulate statistics about all instances. Seems like a nice way to organise things."

@roosterboy. thank you so much to explain in details.

I've read through, think I kind of getting it...But I need to re read a few tims and spend more time to let it sink in.

It sounds a bit like Class, as there is an inheritance sort of quality in it , but I know it is not Class because instances from Struct is unique on its own.

Thanks guys~

1      

Hacking with Swift is sponsored by RevenueCat

SPONSORED Spend less time managing in-app purchase infrastructure so you can focus on building your app. RevenueCat gives everything you need to easily implement, manage, and analyze in-app purchases and subscriptions without managing servers or writing backend code.

Get Started

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.