Nico
Nico

Reputation: 6359

Strange function-like property – can someone explain this piece of Swift code?

I found this piece of code regarding sections in a table view in order to make an index in a table view:

class User: NSObject {
    let namex: String
    var section: Int?

    init(name: String) {
        self.namex = name
    }
}

// custom type to represent table sections
class Section {
    var users: [User] = []

    func addUser(user: User) {
        self.users.append(user)
    }
}

// raw user data
let names = [
    "Clementine",
    "Bessie",
    "Annis",
    "Charlena"
]

// `UIKit` convenience class for sectioning a table
let collation = UILocalizedIndexedCollation.currentCollation() as UILocalizedIndexedCollation

// table sections
var sections: [Section] {
    // return if already initialized
    if self._sections != nil {
        return self._sections!
    }

    // create users from the name list
    var users: [User] = names.map { namess in
        var user = User(name: namess)
        user.section = self.collation.sectionForObject(user, collationStringSelector: "namex")
        return user
    }

    // create empty sections
    var sections = [Section]()
    for i in 0..<self.collation.sectionIndexTitles.count {
        sections.append(Section())
    }

    // put each user in a section
    for user in users {
        sections[user.section!].addUser(user)
    }

    // sort each section
    for section in sections {
        section.users = self.collation.sortedArrayFromArray(section.users, collationStringSelector: "namex") as [User]
    }

    self._sections = sections

    return self._sections!

}
var _sections: [Section]?

The part that I didn't understand is this:

// table sections
var sections: [Section] {
    // return if already initialized
    if self._sections != nil {
        return self._sections!
    }

    // etc...

    return self._sections!

}
var _sections: [Section]?

My questions are:

What does that mean var sections: [Section] { }? I guess it's not a function as there is no func keyword in front.

What is this var _sections: [Section]? What's the reason to place an _ in front?

Upvotes: 1

Views: 231

Answers (2)

Airspeed Velocity
Airspeed Velocity

Reputation: 40965

It is very similar to a function despite the absence of keywords – it’s a computed property.

These look like variables, but act like functions. They can be read-only (get but not set), or can have both a get and a set version. Here’s a simpler example:

var y = 3

var x: Int {
    get { return 2*y }
}

println(x)  // prints 6
y += 1
println(x)  // prints 8

var z: Int {
    get { return y }
    set(newVal) { y = newVal }
}

println(z)  // prints 4
z = 10      // sets y to 10
println(x)  // prints 20 (2*10)

When it’s only a get, you can omit the keyword, which is how it’s being done in the version in your question. The declaration of x above could have been written without it:

var x: Int {
    return 2*y
}

The var _sections in your example is playing a similar role to the y variable in the above code – it’s the underlying data from which the computed property result is derived. The reason for the _ is just to indicate that it is a internal implementation detail. The underscore’s not meaningful to Swift itself, that’s just a naming convention people use.

Upvotes: 3

katfang
katfang

Reputation: 2030

It's a read-only computed property. They act like properties, but are computed each time. You can read more about it in the docs. Check out the section on "Computed Properties" as well as the "Read-Only Computed Properties" section to understand the shorthand.

Upvotes: 1

Related Questions