- Swift Tutorial
- Swift - Home
- Swift - Overview
- Swift - Environment
- Swift - Basic Syntax
- Swift - Variables
- Swift - Constants
- Swift - Literals
- Swift - Comments
- Swift Operators
- Swift - Operators
- Swift - Arithmetic Operators
- Swift - Comparison Operators
- Swift - Logical Operators
- Swift - Assignment Operators
- Swift - Bitwise Operators
- Swift - Misc Operators
- Swift Advanced Operators
- Swift - Operator Overloading
- Swift - Arithmetic Overflow Operators
- Swift - Identity Operators
- Swift - Range Operators
- Swift Data Types
- Swift - Data Types
- Swift - Integers
- Swift - Floating-Point Numbers
- Swift - Double
- Swift - Boolean
- Swift - Strings
- Swift - Characters
- Swift - Type Aliases
- Swift - Optionals
- Swift - Tuples
- Swift - Assertions and Precondition
- Swift Control Flow
- Swift - Decision Making
- Swift - if statement
- Swift - if...else if...else Statement
- Swift - if-else Statement
- Swift - nested if statements
- Swift - switch statement
- Swift - Loops
- Swift - for in loop
- Swift - While loop
- Swift - repeat...while loop
- Swift - continue statement
- Swift - break statement
- Swift - fall through statement
- Swift Collections
- Swift - Arrays
- Swift - Sets
- Swift - Dictionaries
- Swift Functions
- Swift - Functions
- Swift - Nested Functions
- Swift - Function Overloading
- Swift - Recursion
- Swift - Higher-Order Functions
- Swift Closures
- Swift - Closures
- Swift-Escaping and Non-escaping closure
- Swift - Auto Closures
- Swift OOps
- Swift - Enumerations
- Swift - Structures
- Swift - Classes
- Swift - Properties
- Swift - Methods
- Swift - Subscripts
- Swift - Inheritance
- Swift-Overriding
- Swift - Initialization
- Swift - Deinitialization
- Swift Advanced
- Swift - ARC Overview
- Swift - Optional Chaining
- Swift - Error handling
- Swift - Concurrency
- Swift - Type Casting
- Swift - Nested Types
- Swift - Extensions
- Swift - Protocols
- Swift - Generics
- Swift - Access Control
- Swift - Function vs Method
- Swift - SwiftyJSON
- Swift - Singleton class
- Swift Random Numbers
- Swift Opaque and Boxed Type
- Swift Useful Resources
- Swift - Compile Online
- Swift - Quick Guide
- Swift - Useful Resources
- Swift - Discussion
Swift - Properties
Properties are the variables or constants that are related to a particular class, structure or enumeration. They are generally used to define the characteristics of instances of class, structure or enumeration. Properties can be further classified into Stored properties and Computed properties. Stored properties are used to Store constant and variable values as an instance whereas computed properties are used to calculate a value rather than storing the value.
Both Stored and Computed properties are associated with instance type. When the properties are associated with its type values then it is defined as 'Type Properties'. Stored and computed properties are usually associated with instances of a particular type. However, properties can also be associated with the type itself. Such properties are known as type properties.
Stored Properties
The stored property stores the constant or variable values as a part of an instance of a particular class or structure. They can be either variable stored property or constant stored property. The stored properties of constants are defined by the 'let' keyword and Stored properties of variables are defined by the 'var' keyword.
During the definition of stored property, we are allowed to provide 'default value’. Also at the time of initialization, we can initialize and modify the initial values of the stored property.
Syntax
Following is the syntax of stored property −
struct structureName{ var propertyName = initialValue let propertyName = initialValue }
Example
Swift program to demonstrate properties in structure.
// Structure struct Number { // Stored Property without default value var digits: Int // Stored Property with default value let pi = 3.1415 } // Instance of structure var n = Number(digits: 12345) // Assigning a value to the property n.digits = 67 // Accessing the properties of the structure print("\(n.digits)") print("\(n.pi)")
Output
It will produce the following output −
67 3.1415
Example
Another method to have stored property is to have constant structures. So the whole instance of the structures will be considered as 'Stored Properties of Constants'.
// Structure struct Number{ // Variable Stored Properties var digits: Int // Constant stored property let numbers = 3.1415 } // Constant Instance of structure let n = Number(digits: 12345) // Accessing the properties of structure print("\(n.digits)") print("\(n.numbers)") /* Structure is a value type so when the instance of the structure is marked as a constant type, then all the properties of that structure is also considered as a constant so we wouldn't be able to change the value of the properties even if they are of variable type. But this case doesn't happen in class because a class is a reference type */ n.numbers = 8.7
Output
It will produce the following output −
main.swift:25:3: error: cannot assign to property: 'numbers' is a 'let' constant n.numbers = 8.7 ~~^~~~~~~ main.swift:8:4: note: change 'let' to 'var' to make it mutable let numbers = 3.1415 ^~~ var
Instead of reinitializing the 'number' to 8.7, it will return an error message indicating that the 'number' is declared as constant.
Lazy Stored Property
Swift provides a flexible property called 'Lazy Stored Property’, whose initial value is not calculated until the first time it is used. Such types of properties are useful when the initial value of a property is expensive to create, when the initial value is not required immediately, etc.
To declare a stored property as a lazy stored property, we have to use a lazy modifier before the variable declaration. Also, the lazy property is always of variable type because the initial value of the lazy property may not be retrieved until the initialization of the instance has been completed. Whereas the constant property always has value before initialisation and we cannot change the value of the constant property so they are not allowed to declare as lazy property.
Syntax
Following is the syntax of lazy stored property −
class structureName{ lazy var propertyName = }
Example
Swift program to demonstrate lazy property in class.
// Define a class named 'sample' class Sample { // Lazy property of type 'number' lazy var no = Number() } // Define a class named 'number' class Number { // Property var name = "Swift" } // Create an instance of 'Sample' class var firstSample = Sample() // Accessing the lazy property 'no' and then accessing its 'name' property print(firstSample.no.name)
Output
It will produce the following output −
Swift
Instance Variables
In Objective C, Stored properties also have instance variables for backup purposes to store the values declared in stored property.
Swift 4 integrates both these concepts into a single 'stored property' declaration. Instead of having a corresponding instance variable and backup value 'stored property' contains all integrated information defined in a single location about the variable property by variable name, data type and memory management functionalities.
Computed Properties
Apart from stored property Swift also supports one more type of property which is computed property. Computed property does not store values directly instead it provides a getter and an optional setter to retrieve and set other properties and values indirectly. Where the getter method is called when we want to access the property and the setter method is called when we want to modify the property.
To declare a computed property we have to always use the var keyword along with the property name type and the braces{} that contain getter and setter.
Syntax
Following is the syntax of computed property −
struct structureName{ var propertyName : propertyType{ get{} set{} } }
Example
Swift program to demonstrate computed property in the class.
// Class class sample { // Stored properties var no1 = 0.0, no2 = 0.0 var length = 300.0, breadth = 150.0 // Computed properties var middle: (Double, Double) { get{ return (length / 2, breadth / 2) } set(axis){ no1 = axis.0 - (length / 2) no2 = axis.1 - (breadth / 2) } } } // Instance of class var result = sample() // Accessing and initializing properties print(result.middle) result.middle = (0.0, 10.0) print(result.no1) print(result.no2)
Output
It will produce the following output −
(150.0, 75.0) -150.0 -65.0
When a computed property leaves the new value as undefined, the default value will be set for that particular variable.
Computed Properties as Read-Only Properties
A read-only property in computed property is defined as a property with getter but no setter. It is always used to return a value. The variables are further accessed through a '.' Syntax but cannot be set to another value.
Example
class film { var head = "" var duration = 0.0 // Computed property as a read-only property var metaInfo: [String:String] { return [ "head": self.head, "duration":"\(self.duration)" ] } } // Instance of class var movie = film() // Initialzing and accessing properties movie.head = "Swift Properties" movie.duration = 3.09 print(movie.metaInfo["head"]!) print(movie.metaInfo["duration"]!)
Output
It will produce the following output −
Swift Properties 3.09
Property Observers
Property observer allows us to observe and respond to the changes that happen in the value of the property. Whenever the value of the property is set or even if the new value is equal to the current value still the property observer called.
Property observers are available for both stored and computed properties and also available if the property is defined or inherited. For inherited property (either stored or computed) add property observer by overriding the specified property of the inherited class or subclass and for defined computed property, we can use property setter instead of property observer.
Swift supports two types of property observers −
willSet − It is called just before the value of the property is stored. It passes a constant parameter as a new value of the property. We are allowed to specify the name of the parameter in the implementation of willSet. If we do not provide the name of the parameter, then it will provide a default parameter with the name ‘newValue’ that represents the new value of the given property.
didSet − It is called immediately after the new value of the property is set. It passes a constant parameter that contains the old value of the property. We are allowed to specify the name of the parameter in the implementation of didSet. If we do not provide the name of the parameter, then it will provide a default parameter with the name ‘oldValue’ that represents the old value of the given property.
Example
// Define class class Samplepgm { var counter: Int = 0{ // WillSwt property observer willSet(newTotal){ print("Total Counter is: \(newTotal)") } // didSet property observer didSet{ if counter > oldValue { print("Newly Added Counter \(counter - oldValue)") } } } } // Instance of class let NewCounter = Samplepgm() // Accessing property NewCounter.counter = 100 NewCounter.counter = 800
Output
It will produce the following output −
Total Counter is: 100 Newly Added Counter 100 Total Counter is: 800 Newly Added Counter 700
Property Wrapper
In Swift, property wrappers are used to add a layer between the code that manages how a property is going to be stored and the code that defines a property. Or we can say that property wrappers are used to encapsulate the property behaviour in a reusable manner. They are commonly used to add additional functionality to a property. The @propertyWrapper attribute is used to define a property wrapper.
Example
@propertyWrapper struct Ten { private var num = 0 var wrappedValue: Int { get { return num} set { num = min(newValue, 18) } } } struct Rectangle { @Ten var length : Int @Ten var height : Int } var obj = Rectangle() print(obj.length) obj.length = 11 print(obj.length)
Output
It will produce the following output −
0 11
Local and Global Variables
Local and global variables are declared for computing and observing the properties.
Local Variables | Global Variables |
---|---|
Variables that are defined within a function, method, or closure context. | Variables that are defined outside function, method, closure, or type context. |
Used to store and retrieve values. | Used to store and retrieve values. |
Stored properties is used to get and set the values. | Stored properties is used to get and set the values. |
Computed properties are also used. | Computed properties are also used. |
Type Properties
As we know instance property always belongs to an instance of a specified type. So whenever we create a new instance it always contains a set of values for the properties and they are separated from another instance.
However, sometimes we want a property that belongs to itself not to any instance. So this problem is solved by the Type property. The type property is a special property that belongs to itself and will have only one copy, regardless of how many instances of that type are created. The stored type property can be a constant or variable whereas computed type properties are always variable.
Type properties are defined in the Type definition section with curly braces {} and the scope of the variables is also defined previously. For defining type properties for value types 'static' keyword is used and for class types 'class' keyword is used.
Syntax
struct Structname { static var storedTypeProperty = " " static var computedTypeProperty: Int { // return an Int value here } } enum Enumname { static var storedTypeProperty = " " static var computedTypeProperty: Int { // return an Int value here } } class Classname { class var computedTypeProperty: Int { // return an Int value here } }
Querying and Setting Properties
Just like instance properties Type properties are queried and set with '.' Syntax just on the type alone instead of pointing to the instance.
Example
struct StudMarks { // Type properties static let markCount = 97 static var totalCount = 0 var InternalMarks: Int = 0 { didSet { if InternalMarks > StudMarks.markCount { InternalMarks = StudMarks.markCount } if InternalMarks > StudMarks.totalCount { StudMarks.totalCount = InternalMarks } } } } // Instances of structure var stud1Mark1 = StudMarks() var stud1Mark2 = StudMarks() // Accessing property stud1Mark1.InternalMarks = 98 print(stud1Mark1.InternalMarks) stud1Mark2.InternalMarks = 87 print(stud1Mark2.InternalMarks)
Output
It will produce the following output −
97 87