DEV Community


Posted on

Swift - properties


Properties associate a value with a particular class, structure or enumeration.

  • Stored properties store constant and variable values as part of an instance.
  • computed properties calculate (rather than store) a value.

Stored Properties

A stored property is a constant or variable that’s stored as part of an instance of a particular class or structure. Stored properties can be either variable stored properties (introduced by the var keyword) or constant stored properties (introduced by the let keyword).

You can provide a default value for a stored property as part of its definition. You can also set and modify the initial value for a stored property during initialization. This is true even for constant stored properties,

struct FixedLengthRange {
    var firstValue: Int
    let length: Int
var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)
// the range represents integer values 0, 1, and 2
rangeOfThreeItems.firstValue = 6
// the range now represents integer values 6, 7, and 8

Enter fullscreen mode Exit fullscreen mode

lazy stored properties

A lazy stored property is a property where initial value isn't calculated until the first value is used.

  • lazy properties are useful when the initial value for a property is dependent on outside factors whose values aren't known until after an instance initialisation is complete.
class DataImporter {
    var filename = "data.txt"

class DataManager {
    lazy var importer = DataImporter()
    var data: [String] = []

let manager = DataManager()"Some data")"Some more data")
// the DataImporter instance for the importer property hasn't yet been created
Enter fullscreen mode Exit fullscreen mode

Computed properties

In addition to stored properties, classes, structure and enumeration can define computed properties, which don't actually store a value .Instead, they provide a getter and an optional setter to retrieve and set other properties and values indirectly .

struct Point {
    var x = 0.0, y = 0.0
struct Size {
    var width = 0.0, height = 0.0
struct Rect {
    var origin = Point()
    var size = Size()
    var center: Point {
        get {
            let centerX = origin.x + (size.width / 2)
            let centerY = origin.y + (size.height / 2)
            return Point(x: centerX, y: centerY)
        set(newCenter) {
            origin.x = newCenter.x - (size.width / 2)
            origin.y = newCenter.y - (size.height / 2)
var square = Rect(origin: Point(x: 0.0, y: 0.0),
                  size: Size(width: 10.0, height: 10.0))
let initialSquareCenter = = Point(x: 15.0, y: 15.0)
print("square.origin is now at (\(square.origin.x), \(square.origin.y))")
// Prints "square.origin is now at (10.0, 10.0)"
Enter fullscreen mode Exit fullscreen mode

Read-only computed properties

A computed property with a getter but no setter is known as read-only computed property

Property observer

Property observers observes and respond to changes in a property value.

we can add property observer in following places

  • Stored property that you define
  • Stored property that you inherit
  • computed property that you inherit

You have the option to define either or both of these observers on a property:

  • willSet is called just before the value is stored.
  • didSet is called immediately after the new value is stored.
class StepCounter {
    var totalSteps: Int = 0 {
        willSet(newTotalSteps) {
            print("About to set totalSteps to \(newTotalSteps)")
        didSet {
            if totalSteps > oldValue  {
                print("Added \(totalSteps - oldValue) steps")
let stepCounter = StepCounter()
stepCounter.totalSteps = 200
// About to set totalSteps to 200
// Added 200 steps
Enter fullscreen mode Exit fullscreen mode

Property wrappers

A property wrapper adds a layer of separation between code that manages how a property is stored and the code that defines a property.

To define a property wrapper, you make a structure, enumeration, or class that defines a wrappedValue property.

struct TwelveOrLess {
    private var number = 0
    var wrappedValue: Int {
        get { return number }
        set { number = min(newValue, 12) }
//setter ensures that new value is less than 12
Enter fullscreen mode Exit fullscreen mode

You apply a wrapper to a property by writing the wrapper’s name before the property as an attribute.

struct SmallRectangle {
    @TwelveOrLess var height: Int
    @TwelveOrLess var width: Int
Enter fullscreen mode Exit fullscreen mode

Top comments (0)