Swift – Auto Closures ”; Previous Next A closure is a self-contained block of functionality that can passed around and used inside the code to perform any specific task. It can be assigned to a variable or passed as a function parameter. It can capture values from its surrounding context which is useful while working with asynchronous tasks. Swift supports various types of closures like escaping, non-escaping, and Auto closures. In this chapter, we will discuss about auto closure in detail. Auto Closures in Swift Swift supports a special type of closure that is known as auto closure. An auto closure is automatically created to wrap a statement that will passed as an argument to a specified function. It does not take any argument and only returns the value of the expression that it wraps inside at the time of calling. It is generally used with the function that takes closure as an argument and allows us to delay the evaluation of the expression until it is called or required. Auto closure provides a concise syntax and is useful for passing a simple expression to the function as an argument instead of creating a separate closure. Also, remember that do not overuse auto closure because it makes our code harder to read. Declaring Auto Closure To declare a closure as an auto closure we have to use the @autoclosure keyword. Syntax Following is the syntax for auto closure − func functionname(_closureParameter: @autoclosure() -> ReturnType){ // body } Example Swift simple program to demonstrate auto closure. import Foundation // Defining a function that takes an auto-closure func functionForAutoclosure(myClosure: @autoclosure () -> Void) { print(“Performing Action”) myClosure() } // Calling the function with a closure as an argument functionForAutoclosure(myClosure: print(“Hello! This is the auto closure”)) Output It will produce the following output − Performing Action Hello! This is the auto closure Example Swift program to add two numbers using auto closure. // Function to find the sum of two numbers using auto-closure func addition(_ x: Int, _ y: Int, add: @autoclosure () -> Int) { let output = x + y + add() print(“The sum of (x) and (y) is (output)”) } // Calling the function with a closure as an argument addition(2, 4, add: 7 + 8) Output It will produce the following output − The sum of 2 and 4 is 21 Auto Closures as an Escape Closure In Swift, we are allowed to escape an auto closure. An escaping closure is a special closure that passes as an argument to a function but is called after the function return. Auto closure and escaping closure both are different terms but we can combine them to delay the evaluation of the expression until it is required. To declare an auto closure as an escape closure we have to use both the @autoclosure and @escaping keywords together. Syntax Following is the syntax for auto closure as an escape closure − func functionName(_closureParameter: @autoclosure @escaping() -> ReturnType){ // body } Example Swift simple program to demonstrate auto closure as an escaping closure. import Foundation class AutoClosureExample { var queue: [() -> Void] = [] // Method that takes an auto closure as an escaping closure func closureToQueue(_ myClosure: @autoclosure @escaping () -> Void) { queue.append(myClosure) } // Method that executes the closures in the queue func runClosure() { for closure in queue { closure() } } } // Creating object of AutoClosureExample class let obj = AutoClosureExample() // Using an auto closure as an escaping closure obj.closureToQueue(print(“My Closure 1”)) obj.closureToQueue(print(“My Closure 2″)) // Activating the passage of time DispatchQueue.main.asyncAfter(deadline: .now() + 2) { // Execute the closures in the queue obj.runClosure() } Output It will produce the following output − My Closure 1 My Closure 2 This program will run on Xcode or local Swift playground. It does not work on online Swift compilers because online Swift compilers are not compatible with executing asynchronous operations. Print Page Previous Next Advertisements ”;
Category: swift
Swift – ARC Overview
Swift – ARC Overview ”; Previous Next Automatic Reference Counting in Swift Automatic Reference Counting(ARC) is a memory management mechanism used by Swift, it automatically tracks and manages the allocation and deallocation of objects’s memory. Or we can say that it is used to initialize and deinitialize the system resources thereby releasing memory spaces used by the class instances when the instances are no longer needed. It keeps track of information about the relationships between the instances to manage the memory resources effectively. ARC is generally applicable only to instances of classes because they are reference types. Working of ARC ARC allocates a chunk of memory to store the information whenever a new class instance is created by init(). Information about the instance type and its values are stored in the memory. When the class instance is no longer needed it automatically frees the memory space by deinit() for further class instance storage and retrieval. ARC keeps in track of currently referring class instances properties, constants and variables so that deinit() is applied only to those unused instances. ARC maintains a ”strong reference” to those class instance properties, constants and variables to restrict deallocation when the class instance is currently in use. Example Swift program to demonstrate ARC. class StudDetails { // Properties var stname: String var mark: Int // Initializer to initialize instances of the class init(stname: String, mark: Int) { self.stname = stname self.mark = mark } // Deinitializer to deinitialize the instances of // the class when they are no longer required deinit { print(“Deinitialized (self.stname)”) print(“Deinitialized (self.mark)”) } } // Creating class instance var obj1 = StudDetails( stname:”Swift”, mark:98) // Creating another class instance var obj2: StudDetails? = StudDetails(stname: “iOS”, mark: 95) // Setting anotherObj to nil to deallocate the memory obj2 = nil Output It will produce the following output − Deinitialized iOS Deinitialized 95 Strong Reference Cycles Between Class Instances in Swift ARC is used to automatically manage memory by keeping track of object references. However, there is a challenge faced by the developers which is the creation of a strong reference cycle, where two or more objects have strong references to each other which prevents their reference counts from reaching zero and due to this a memory leakage happens. Example Swift program to demonstrate strong reference cycles between class instances in Swift. class studmarks { let name: String var stud: student? // Initializer init (name: String) { print(“Initializing: (name)”) self.name = name } // Deinitializer deinit { print(“Deallocating: (self.name)”) } } class student { let name: String var strname: studmarks? // Initializer init (name: String) { print(“Initializing: (name)”) self.name = name } // Deinitializer deinit { print(“Deallocating: (self.name)”) } } // Declare optional variables for instances var shiba: studmarks? var mari: student? shiba = studmarks(name: “Swift 4”) mari = student(name: “ARC”) // Create a strong reference cycle by assigning references to each other shiba!.stud = mari mari!.strname = shiba Output It will produce the following output − Initializing: Swift 4 Initializing: ARC To resolve strong reference cycles Swift provides Weak and Unowned References. These references are used to enable one instance to refer to other instances in a reference cycle. Then the instances may refer to every instance instead of caring about a strong reference cycle. Weak References It is an optional reference to an object that does not keep a strong hold on the object. It will return nil when the object it refers to is deallocated. It is generally used where the referenced object’s lifecycle is not guaranteed to outlive the referencing object. It is commonly used for relationships where the referenced object can deallocate independently. We can declare weak references using the weak Keyword. Syntax Following is the syntax for weak reference − class Class1 { var name: Name? } class Name { weak var teacher: Class1? } Example Swift program to demonstrate weak references. class module { let name: String init(name: String) { self.name = name } var sub: submodule? deinit { print(“(name) Is The Main Module”) } } class submodule { let number: Int init(number: Int) { self.number = number } weak var topic: module? deinit { print(“Sub Module with its topic number is (number)”) } } var toc: module? var list: submodule? toc = module(name: “ARC”) list = submodule(number: 4) toc!.sub = list list!.topic = toc toc = nil list = nil Output It will produce the following output − ARC Is The Main Module Sub Module with its topic number is 4 Unowned References It is a non-optional reference to an object that does not keep a strong hold on the object as compared to a weak reference. It assumed that the reference object will never become nil, while the reference object is still alive. It is generally used where you know that the referenced object’s life is guaranteed to be at least as long as the referencing object’s lifetime. It is commonly used for relationships where the referenced object has the same or longer lifetime as compared to the referencing object. We can declare unowned references using the unowned Keyword. Syntax Following is the syntax for unowned reference − class Class1 { var name: Name? } class Name { unowned var teacher: Class1 } Example Swift program to demonstrate Unowned references. class student { let name: String var section: marks? init(name: String) { self.name = name } deinit { print(“(name)”) } } class marks { let marks: Int unowned let stname: student init(marks: Int, stname: student) { self.marks = marks
Swift – Deinitialization
Swift – Deinitialization ”; Previous Next Deinitialization is the process of releasing memory resources when an instance of the class is not required. Deinitializers work only with classes, not with the structure or enumeration. It is not necessary that Swift will immediately call a deinitializer when the instance is no longer needed, it will be called before the instance is deallocated and this timing is managed by the automatic reference counting(ARC) system. A class can have only one deinitializer. Deinitializers are automatically called developers are not allowed to call them manually The timing of calling the deinitializer is not explicitly controlled by the developer. It is automatically determined by the ARC. Circular references can prevent deinitialization. The deinitializer of the superclass is inherited by their subclasses and the deinitializer of the superclass is called after the implementation of the subclass deinitializer(even if the subclass does not have its own deinitializer). As we know the instance is not deallocated until after its deinitializer is called, so it means that the deinitialzer can access and modify the instance’s property. Defining Deinitializer in Class In Swift, we can define a deinitializer in a class using “deinit” keyword. The code present inside the deinitializer will execute when the instance of the class is deallocated. The Deinitializer does not take any parameter. Syntax Following is the syntax of the deinitializer class className{ // Properties and methods of class // Deinitializer deinit { // statement } } Example Swift program to create deinitializer. // Defining class class Student { // Property of class var name: String // Initializer to initialize instance init(name: String) { self.name = name print(“(name) is initialized”) } // Deinitializer to deinitialize instance deinit { print(“(name) is deinitialized”) } } // Creating and initializing instances of the student class var object1: Student? = Student(name: “Mira”) var object2: Student? = Student(name: “Jenni”) // Deinitializers will be called when instances are deallocated object1 = nil object2 = nil Output It will produce the following output − Mira is initialized Jenni is initialized Mira is deinitialized Jenni is deinitialized Deallocating Memory Space Using Deinitializer In Swift, deinitialization is handled by the Automatic Reference Counting(ARC). Automatic Reference Counting is a memory management mechanism that is used to keep track of the instance references and deallocate objects when they are no longer needed. Although Swift automatically deallocates memory resources we are not required to perform manual cleaning, but if we are using our resources, then we may have to clean them up manually. For example, if we create a custom class to open a file and write some data to it, we might need to close the file before the class instance is deallocated. Now, we will see how the deinitializer works − Step 1 − Create and initialize a new instance of the class using “init” initializer. Step 2 − Use the instance of the class with strong references. The instance of the class will stay alive as long as there is at least one strong reference to that object. Step 3 − When the last strong reference to an object is terminated at that time deinitializer will be automatically called by the ARC before the object is deallocated. Step 4 − Now the code present in the deinitializer is executed and the instance of the given class will be deallocated. The memory is free for other objects. So this is how deinitializer works. Example Swift program to demonstrate how deinitializer works. var counter = 0; // for reference counting class baseclass { init() { counter++; } deinit { counter–; } } var print: baseclass? = baseclass() print(counter) print = nil print(counter) Output It will produce the following output − 1 0 When print = nil statement is omitted the values of the counter remain the same since it is not deinitialized. Example var counter = 0; // for reference counting class baseclass { init() { counter++; } deinit { counter–; } } var print: baseclass? = baseclass() print(counter) print(counter) Output It will produce the following output − 1 1 Print Page Previous Next Advertisements ”;
Swift – Optional Chaining
Swift – Optional Chaining ”; Previous Next The process of querying, calling properties, subscripts and methods on an optional that may be ”nil” is defined as optional chaining. Optional chaining return two values − if the optional contains a ”value” then calling its related property, methods and subscripts returns values if the optional contains a ”nil” value all its its related property, methods and subscripts returns nil Since multiple queries to methods, properties and subscripts are grouped together failure to one chain will affect the entire chain and results in ”nil” value. Optional Chaining as an Alternative to Forced Unwrapping Optional chaining is specified after the optional value with ”?” to call a property, method or subscript when the optional value returns some values. Optional Chaining ”?” Access to methods,properties and subscriptsOptional Chaining ”!” to force Unwrapping. ? is placed after the optional value to call property, method or subscript. ! is placed after the optional value to call property, method or subscript to force unwrapping of value. Fails gracefully when the optional is ”nil”. Forced unwrapping triggers a run time error when the optional is ”nil”. Program for Optional Chaining with ”!” Example class ElectionPoll { var candidate: Pollbooth? } class Pollbooth { var name = “MP” } let cand = ElectionPoll() let candname = cand.candidate!.name Output When we run the above program using playground, we get the following result − main/main.swift:10: Fatal error: Unexpectedly found nil while unwrapping an Optional value Current stack trace: 0 libswiftCore.so 0x00007fd880a40dc0 _swift_stdlib_reportFatalErrorInFile + 112 1 libswiftCore.so 0x00007fd88070a191 <unavailable> + 1442193 2 libswiftCore.so 0x00007fd880709eb6 <unavailable> + 1441462 3 libswiftCore.so 0x00007fd880709caa <unavailable> + 1440938 4 libswiftCore.so 0x00007fd8807096d0 _assertionFailure(_:_:file:line:flags:) + 315 6 swift-frontend 0x000055a564ac0b3d <unavailable> + 26479421 7 swift-frontend 0x000055a563df4db9 <unavailable> + 13061561 8 swift-frontend 0x000055a563bc54c6 <unavailable> + 10769606 9 swift-frontend 0x000055a563bc19b6 <unavailable> + 10754486 10 swift-frontend 0x000055a563bc10a7 <unavailable> + 10752167 11 swift-frontend 0x000055a563bc341e <unavailable> + 10761246 12 swift-frontend 0x000055a563bc273d <unavailable> + 10757949 13 swift-frontend 0x000055a563a94a39 <unavailable> + 9521721 14 libc.so.6 0x00007fd880017d90 <unavailable> + 171408 15 libc.so.6 0x00007fd880017dc0 __libc_start_main + 128 16 swift-frontend 0x000055a563a94295 <unavailable> + 9519765 Stack dump: 0. Program arguments: /opt/swift/bin/swift-frontend -frontend -interpret main.swift -disable-objc-interop -color-diagnostics -new-driver-path /opt/swift/bin/swift-driver -empty-abi-descriptor -resource-dir /opt/swift/lib/swift -module-name main 1. Swift version 5.7.3 (swift-5.7.3-RELEASE) 2. Compiling with the current language version 3. While running user code “main.swift” Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it): /opt/swift/bin/swift-frontend(+0x551a103)[0x55a56869a103] /opt/swift/bin/swift-frontend(+0x551802e)[0x55a56869802e] /opt/swift/bin/swift-frontend(+0x551a48a)[0x55a56869a48a] /lib/x86_64-linux-gnu/libc.so.6(+0x42520)[0x7fd880030520] /opt/swift/lib/swift/linux/libswiftCore.so(+0x160195)[0x7fd88070a195] /opt/swift/lib/swift/linux/libswiftCore.so(+0x15feb6)[0x7fd880709eb6] /opt/swift/lib/swift/linux/libswiftCore.so(+0x15fcaa)[0x7fd880709caa] /opt/swift/lib/swift/linux/libswiftCore.so($ss17_assertionFailure__4file4line5flagss5NeverOs12StaticStringV_A2HSus6UInt32VtF+0x13b)[0x7fd88070980b] [0x7fd87ece717e] /opt/swift/bin/swift-frontend(+0x1940b3d)[0x55a564ac0b3d] /opt/swift/bin/swift-frontend(+0xc74db9)[0x55a563df4db9] /opt/swift/bin/swift-frontend(+0xa454c6)[0x55a563bc54c6] /opt/swift/bin/swift-frontend(+0xa419b6)[0x55a563bc19b6] /opt/swift/bin/swift-frontend(+0xa410a7)[0x55a563bc10a7] /opt/swift/bin/swift-frontend(+0xa4341e)[0x55a563bc341e] /opt/swift/bin/swift-frontend(+0xa4273d)[0x55a563bc273d] /opt/swift/bin/swift-frontend(+0x914a39)[0x55a563a94a39] /lib/x86_64-linux-gnu/libc.so.6(+0x29d90)[0x7fd880017d90] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x80)[0x7fd880017e40] /opt/swift/bin/swift-frontend(+0x914295)[0x55a563a94295] Illegal instruction (core dumped) The above program declares ”election poll” as class name and contains ”candidate” as membership function. The subclass is declared as ”poll booth” and ”name” as its membership function which is initialized as ”MP”. The call to the super class is initialized by creating an instance ”cand” with optional ”!”. Since the values are not declared in its base class, ”nil” value is stored thereby returning a fatal error by the force unwrapping procedure. Program for Optional Chaining with ”?” Example class ElectionPoll { var candidate: Pollbooth? } class Pollbooth { var name = “MP” } let cand = ElectionPoll() if let candname = cand.candidate?.name { print(“Candidate name is (candname)”) } else { print(“Candidate name cannot be retreived”) } Output When we run the above program using playground, we get the following result − Candidate name cannot be retreived The program above declares ”election poll” as class name and contains ”candidate” as membership function. The subclass is declared as ”poll booth” and ”name” as its membership function which is initialized as ”MP”. The call to the super class is initialized by creating an instance ”cand” with optional ”?”. Since the values are not declared in its base class ”nil” value is stored and printed in the console by the else handler block. Defining Model Classes for Optional Chaining & Accessing Properties Swift 4 language also provides the concept of optional chaining, to declare more than one subclasses as model classes. This concept will be very useful to define complex models and to access the properties, methods and subscripts sub properties. Example class rectangle { var print: circle? } class circle { var area = [radius]() var cprint: Int { return area.count } subscript(i: Int) -> radius { get { return area[i] } set { area[i] = newValue } } func circleprint() { print(“The number of rooms is (cprint)”) } var rectarea: circumference? } class radius { let radiusname: String init(radiusname: String) { self.radiusname = radiusname } } class circumference { var circumName: String? var circumNumber: String? var street: String? func buildingIdentifier() -> String? { if circumName != nil { return circumName } else if circumNumber != nil { return circumNumber } else { return nil } } } let rectname = rectangle() if let rectarea = rectname.print?.cprint { print(“Area of rectangle is (rectarea)”) } else { print(“Rectangle Area is not specified”) } Output When we run the above program using playground, we get the following result − Rectangle Area is not specified Calling Methods Through Optional Chaining Example class rectangle { var print: circle? } class circle { var area = [radius]() var cprint: Int { return area.count } subscript(i: Int) -> radius { get { return area[i] } set { area[i] = newValue } } func circleprint() { print(“Area of Circle is: (cprint)”) } var rectarea: circumference? } class radius { let radiusname: String init(radiusname: String) { self.radiusname = radiusname } } class circumference { var circumName: String? var circumNumber: String? var circumarea: String? func buildingIdentifier() -> String? { if circumName !=
Swift-Overriding
Swift – Overriding ”; Previous Next Overriding is a very common concept in object-oriented programming languages. Using overriding we are allowed to re-implement a method or property of a superclass in a subclass. It allows us to extend the behaviour of inheritance. While overriding the method or property we are providing a new implementation in the subclass instead of using the the implementation in the superclass. In Swift, we can override the method or the property of the superclass. Access to Superclass Methods, Properties and Subscripts The ”super” keyword is used as a prefix to access the methods, properties and subscripts declared in the superclass. Overriding Access to methods, properties and subscripts Methods super.somemethod() Properties super.someProperty() Subscripts super[someIndex] Rules for overriding in Swift Following are some rules you should follow while overriding − The overridden method or property in the subclass must have the same signature(name, parameter and return type) as they are in the superclass. Use the super keyword to call the overridden implementation from the superclass in the overriding method. Use the override keyword to override properties. We can override both stored and computed properties. The access level of an overriding method or property cannot be more restrictive than the access level of the overridden method or property in the base class. You are not allowed to override a public method with a private method. So always check the access modifier before overriding. Methods Overriding in Swift In Swift, we are allowed to override methods. The overriding method means a subclass can provide a different implementation for a method that is already defined in the base class. Or we can say that we can customize the behaviour of a superclass method in the subclass. The overridden method in the subclass must have the same signature(name, parameter and return type) as the base class and the compiler will determine which method is called according to the type of object. Also, the access level of the overridden method in the subclass must be the same or more permissive than the access level of the method in the superclass. The override method is defined by using the override keyword in the subclass. This keyword is placed before starting the function definition. It tells the compiler that the method will override the method of the superclass. If we do not specify the override keyword then the compiler will give us the error. Syntax Following is the syntax for method overriding − override func methodName(Parameters) -> returntype { Statement return parameters } Example Swift program for method overriding. // Super class class cricket { // Method func show() { print(“Welcome to Swift Super Class”) } } // Sub class class tennis: cricket { // Overriden Method override func show() { print(“Welcome to Swift Sub Class”) } } // Creating instance of subclass let tennisinstance = tennis() // Accessing the override method tennisinstance.show() Output It will produce the following output − Welcome to Swift Sub Class Property Overriding Swift supports property overriding. Just like method overriding, property overriding also provides a way for a subclass to customize the implementation of the properties that are already defined in the base class. We can say that using property overriding, we can provide our own getter and setter for that property or add property observers, which enables the overriding property to observe when the property value changes. The type of the overridden property in the subclass must have the same name and type as the property in the base class. So that the compiler will determine which property(either the superclass property or overridden property) is called according to the type of object. The access level of the overridden method in the subclass must be similar or more permissive than the access level of the property in the superclass. The override property is defined by using the override keyword in the subclass. This keyword is placed before starting the property definition. It tells the compiler that the property will override the property of the superclass. If we do not specify the override keyword, then the compiler will give us the error. Syntax Following is the syntax for property overriding − override var propertyName: type{ // Statement } Example Swift program for property overriding. // Superclass class mySuperClass { // Property var language: String{ return “C++” } } // Subclass class mySubClass: mySuperClass { // Override Property override var language: String{ return “Swift” } } // Creating an instance of a subclass let obj = mySubClass() // Accessing the overridden property print(obj.language) Output It will produce the following output − Swift Overriding Property Getters and Setters Swift allows the user to override the getter and setter of the subclass property, whether the property is stored or computed. The name and the type of the overriding property must be the same as the property present in the base case. So that the compiler knows that you are overriding the property of the base class. In Swift, we are allowed to represent the read-only inherited property as a read-write property by providing both a getter and setter in the subclass while overriding. Whereas we are not allowed to represent the read-write-only inherited property as read-only property. When setter is defined for overriding property the user has to define getter too. If we do not wish to modify the value of the inherited property in the overriding getter, then we can pass the inherited value using ”super.PropertyName” from the getter, where PropertyName represents the name of the overriding property. Example Swift
Swift – Nested Types
Swift – Nested Types ”; Previous Next The nested type is a very powerful tool in Swift programming. Using nested type we can able to easily nest enumerations, classes and structures into other enumerations, classes and structures. Using nested type we can nest an enumeration or class into a structure or vice versa. So we can say that by using nested types we can create complex custom types. Nested types are commonly used to create well-organized and hierarchical programs. They are also used to encapsulate code so that we can easily understand it. They also reduce namespace conflicts. Creating Nested Types We can create nested types by defining a structure into another structure or a class into another class just like the nested functions. We can create multiple structures, classes and enumerations in another structure, class and enumerations. Syntax Following is the syntax of the nested types − Struct Name{ Struct name{ // body } } Using this syntax we can nest classes and enumerations. Example Suppose we are creating a structure of a car in which we have multiple types of features like colour and sunroof. So using nested type we can define each type of specifications. struct Car{ struct Color{ var single: String var double: String var customize: String } struct Sunroof{ var half: String var full: String } } Creating Instance of Nested Types We can create instances of nested types using the dot operator. So simply prefix the name of the outer type followed by the dot operator and then specify the nested type name. Every nested type has its instance. Syntax Following is the syntax for creating instances of nested types − let name = outerTypeName.nestedTypeName(value: type) Or, var name = OuterTypeName(label1:Value, lable2: OuterTypeName.NestedTypeName(label: Value, lable2: Value)) Example Let”s create the instance of the above-nested types − let instance1 = Car.Color(single: “Yellow”, double: “Green Black”, customize: “Blue”) let instance2 = Car.Sunroof(half: “yes”, full: “No”) Or, var myCar = Car(name:”Breeza”, color: Car.Color( single: “Blue”, double: “No”, customize: “White”), sunroof:Car.Sunroof(half: “Yes”, full: “No”)) The complete example is − import Foundation // Outer sturtcure struct Car{ // Nested structure 1 struct Color{ var single: String var double: String var customize: String } // Nested structure 1 struct Sunroof{ var half: String var full: String } // Properties var name: String var color: Color var sunroof:Sunroof } // Creating instance of Car structure var myCar = Car(name:”Breeza”, color: Car.Color(single: “Blue”, double: “No”, customize: “White”), sunroof:Car.Sunroof(half: “Yes”, full: “No”)) // Displaying Data print(“Car name:”, myCar.name) print(“Car Color:”, myCar.color.single) print(“Have half Sunroof:”, myCar.sunroof.half) Output It will produce the following output − Car name: Breeza Car Color: Blue Have half Sunroof: Yes Enumerations within Structure Using nested types it is not necessary that you can only nest a structure into another structure. We can also nest an enumeration inside another structure or vice versa. Example Swift program to nest enumeration inside a structure. import Foundation // Outer structure struct Tutorialspoint { // Nested enum enum Department { case HR case Development case Designing case ContentWriting } // Properties var name: String var location: String var department: Department init(name: String, location: String, department: Department) { self.name = name self.location = location self.department = department } // Method func employeeDetail() { print(“Name: (name)”) print(“Location: (location)”) print(“Department: (department)”) } } let report = Tutorialspoint(name: “Mona”, location: “Hyderabad”, department: .Designing) report.employeeDetail() Output It will produce the following output − Name: Mona Location: Hyderabad Department: Designing Structure within Class Using nested types we are allowed to nest a structure within a class or a class within a structure without getting any error. Example Swift program to nest structure inside another class. import Foundation // Outer class class XYZCollege { // Nested structure struct StudentDetail { var name: String var age: Int var subject: String var year: Int } // Properties var department: String var details: [StudentDetail] init(department: String) { self.department = department self.details = [] } // Method 1 func newStudents(student: StudentDetail) { details.append(student) } // Method 2 func studentsData() { print(“department name: (department):”) for s in details { print(“name: (s.name), age: (s.age), subject: (s.subject), year: (s.year)”) } } } // Creating instances let s = XYZCollege(department: “Science”) let stud1Detail = XYZCollege.StudentDetail(name: “Mona”, age: 19, subject: “Maths”, year: 1) let stud2Detail = XYZCollege.StudentDetail(name: “Pihu”, age: 18, subject: “Chemistry”, year: 1) let stud3Detail = XYZCollege.StudentDetail(name: “Suman”, age: 19, subject: “Maths”, year: 1) // Accessing the methods s.newStudents(student: stud1Detail) s.newStudents(student: stud2Detail) s.newStudents(student: stud3Detail) s.studentsData() Output It will produce the following output − department name: Science: name: Mona, age: 19, subject: Maths, year: 1 name: Pihu, age: 18, subject: Chemistry, year: 1 name: Suman, age: 19, subject: Maths, year: 1 Print Page Previous Next Advertisements ”;
Swift – Classes
Swift – Classes ”; Previous Next Classes in Swift are building blocks of flexible constructs. Similar to constants, variables and functions the user can define class properties and methods. Swift provides us with the functionality that while declaring classes the users need not create interfaces or implementation files. Swift allows us to create classes as a single file and the external interfaces will be created by default once the classes are initialized. Benefits of having Classes Inheritance acquires the properties of one class to another class. Type casting enables the user to check class type at run time. Deinitializers take care of releasing memory resources. Reference counting allows the class instance to have more than one reference. Common Characteristics of Classes and Structures Properties are defined to store values Subscripts are defined as providing access to values Methods are initialized to improve functionality Initial states are defined by initializers Functionality is expanded beyond default values Confirming protocol functionality standards Definition of a Class in Swift In Swift, a class is defined using a class keyword along with the name of the class and curly braces({}). The name of the class always starts with a capital letter such as Employee, not employee and the curly braces contain an initializer, properties methods of the class. Properties − The constants and variables associated with the class are known as the properties of the structure. They are commonly used to define the characteristics of the class. A class can have multiple properties. Methods − Functions associated with the class are known as the methods of the class. They are commonly used to define behaviour associated with the class. They can have parameters and return values. A single class can have multiple methods. Initializer − It is a special method associated with a class. An initializer is used to set up the initial state of a class instance. It is defined using the init keyword. It is called when we create an instance of the class. It can have parameters and default values. Syntax Following is the syntax of the class − class nameClass { // Properties Property 1 : Type Property 2 : Type // Initializer init(){ // statement } // Methods func functionName(){ // Statement } } Example In the following Swift example, we create a class named markStruct with three properties such as studname of String type, mark and mark2 of Int type. class student{ var studname: String var mark: Int var mark2: Int } Swift Class Object An object is known as the instance of the class. It is created according to the blueprint defined by the class. A single class can have multiple objects and they are independent of each other, which means if we modify one instance that doesn”t affect other instances. We can create an object of the class by calling the class initializer. Using this initializer, we can initialize each property by passing the initial value along with the name of the property. Syntax Following is the syntax of the class instance − var objectName = ClassName(propertyName1: Value, propertyName2: value) Example In the following Swift example, we will create an instance of Marks. class Marks { var mark1: Int var mark2: Int var mark3: Int } // Creating a class object using an initializer var myObj = Marks(mark1: 10, mark2: 20, mark3: 30) Accessing the Properties of the Class in Swift To access the properties of the class we can use a class object followed by a dot(.) and the name of the property. We can also modify the values of the properties with the help of dot(.) syntax. Syntax Following is the syntax for accessing the properties of the class − classObjectName.PropertyName Following is the syntax for modifying the properties of the class − classObjectName.PropertyName = value Example Swift program to access and modify the properties of a class. // Defining a class struct Employee { var name: String var department: String var salary: Int // Initializer init(name: String, department: String, salary: Int){ self.name = name self.department = department self.salary = salary } } // Creating an instance of the Employee class var emp = Employee(name: “Suman”, department: “Designing”, salary: 33000) // Accessing the values of the properties using dot notation print(“Employee Details:”) print(“Name: (emp.name)”) print(“Department: (emp.department)”) print(“Salary: (emp.salary)”) // Modifying the values of the properties using dot notation emp.salary = 40000 // Displaying the updated values print(“nUpdated Value:”) print(“Salary: (emp.salary)”) Output It will produce the following output − Employee Details: Name: Suman Department: Designing Salary: 33000 Updated Value: Salary: 40000 Accessing the Methods of the Class in Swift To access the methods of the class we can use dot notation. Here a class instance is followed by a dot(.) and a method name to access methods. Syntax Following is the syntax for accessing the method of the class − classInstanceName.methodName Example Swift program to access the methods of the class. // Defining a class class Parallelogram { // Properties of class var base: Double var height: Double // Initializer init(base: Double, height: Double){ self.base = base self.height = height } // Method to calculate the area of the Parallelogram func calculateParallelogramArea() -> Double { return base * height } } // Create an instance of the Parallelogram class var myObj = Parallelogram(base: 10.0, height: 9.0) // Calling the calculateParallelogramArea() method let area = myObj.calculateParallelogramArea() print(“Area of the Parallelogram: (area)”) Output It will produce the following output −
Swift – Subscripts
Swift – Subscripts ”; Previous Next Subscript is a special feature provided by Swift to access the element of a collection, sequence and list. It is the most convenient way to get or set values in the collection. We can also get or set values according to their index using subscripts. Even classes, structure and enumeration can define subscripts. A single type can have multiple subscripts. We can use the appropriate subscript to overload according to the type of index value passed to the subscript. We can define a subscript that can take single as well as multiple parameters according to our requirements. Subscript Declaration We can define subscript using the subscript keyword and can take one or more input parameters and return type. It can be read-write or read-only. It allows us to perform queries on the instance by writing one or more values in square brackets followed by the instance name. Syntax Following is the syntax of the subscript − subscript(index: Int) -> Int { get { // Retrieve the value at the specified index } set(newValue) { // Set the value at the specified index } } Following is the syntax of read-only subscript − subscript(index: Int) -> Int { // Return subscript value here } Example Swift program to retrieve values using subscript syntax. // Defining structure struct subexample { let decrementer: Int // Declaring subscript subscript(index: Int) -> Int { return decrementer / index } } // Creating instance of the structure let division = subexample(decrementer: 100) // Retrieving values using subscript syntax print(“The number is divisible by (division[9]) times”) print(“The number is divisible by (division[2]) times”) print(“The number is divisible by (division[3]) times”) print(“The number is divisible by (division[5]) times”) print(“The number is divisible by (division[7]) times”) Output It will produce the following output − The number is divisible by 11 times The number is divisible by 50 times The number is divisible by 33 times The number is divisible by 20 times The number is divisible by 14 times Example Swift program to access values using subscript syntax. // Defining class class daysofaweek { private var days = [“Sunday”, “Monday”, “Tuesday”, “Wednesday”, “Thursday”, “Friday”, “Saturday”] // Declaring subscript subscript(index: Int) -> String { // Retrieve the value at the specified index get { return days[index] } // Set the value at the specified index set(newValue) { self.days[index] = newValue } } } // Creating instance of class var p = daysofaweek() // Accessing elements using subscript print(p[0]) print(p[1]) print(p[2]) print(p[3]) Output It will produce the following output − Sunday Monday Tuesday Wednesday Options in Subscript Subscripts can take single or multiple input parameters of any data type and it can also return a value of any data type. These parameters can have default values. Subscripts can use variadic parameters but they cannot use in-out parameters. Defining multiple subscripts is termed as ”subscript overloading” where a class or structure can provide multiple subscript definitions as required. These multiple subscripts are inferred based on the types of values that are declared within the subscript braces. Example Swift program to access values using subscript syntax. // Defining structure struct Matrix { let rows: Int, columns: Int var print: [Double] // Initializer to create a matrix init(rows: Int, columns: Int) { self.rows = rows self.columns = columns // Initializing the matrix with an array print = Array(repeating: 0.0, count: rows * columns) } // Subscript for accessing and modifying elements in the matrix subscript(row: Int, column: Int) -> Double { get { return print[(row * columns) + column] } set { print[(row * columns) + column] = newValue } } } // Creating an instance var mat = Matrix(rows: 3, columns: 3) // Modifying elements in the matrix using subscript notation mat[0, 0] = 1.0 mat[0, 1] = 2.0 mat[1, 0] = 3.0 mat[1, 1] = 5.0 // Accessing and printing elements from the matrix using subscript notation print(“(mat[0, 0])”) print(“(mat[0, 1])”) print(“(mat[1, 0])”) print(“(mat[1, 1])”) Output It will produce the following output − 1.0 2.0 3.0 5.0 Print Page Previous Next Advertisements ”;
Swift – Arrays
Swift – Arrays ”; Previous Next Arrays are used to store ordered lists of values of the same type. Swift puts strict checking which does not allow you to enter a wrong type in an array, even by mistake. If you assign a created array to a variable, then it is always mutable, which means you can change it by adding, removing, or changing its elements; but if you assign an array to a constant, then that array is immutable, and its size and contents cannot be changed. If you try to change it, then the compiler will throw an error. An array can store duplicate values in different positions. Each element in the array has an index value starting from 0 so that we can access and modify them using that index. Creating Arrays in Swift We can create an array by specifying the type of the array explicitly. Syntax Following is the syntax for creating an array − var someArray : [Type] = [] We can also create an array without specifying its type. In this case, the compiler will automatically get the type of the array based on the assigned value. var someArray = [value1, value2, value3] If you need to create an array with a single value (by repeating it), you can do so using the Array() initializer. var someInts = Array(repeating: “Swift”, count: 4) Example In the following example we are creating 3 different arrays using all the above discussed syntaxes − import Foundation // Defining an array by specifying the type var arr1:[Int] = [11, 44, 55, 77, 88, 22] print(“Contents of arr1 :”, arr1) // Defining an array without specifying the type var arr2 = [101, 404, 550, 770, 880, 222] print(“Contents of arr2 :”, arr2) // Defining an array with a single value var arr3 = Array(repeating: “Tutorialspoint”, count: 3) print(“Contents of arr3 :”, arr3) Output The above program produces the following result − Contents of arr1 : [11, 44, 55, 77, 88, 22] Contents of arr2 : [101, 404, 550, 770, 880, 222] Contents of arr3 : [“Tutorialspoint”, “Tutorialspoint”, “Tutorialspoint”] Modifying and Accessing Arrays in Swift In an array, every element has its own index value starting from 0. So to retrieve a value from an array, pass the index of the value we want to retrieve within square brackets immediately after the name of the array in the subscript syntax. Syntax Following is the syntax for accessing and modifying array − arrayName[indexValue] Here, the index starts from 0 which means the first element can be accessed using the index as 0, the second element can be accessed using the index as 1 and so on. Example import Foundation // Defining and initializing an array var someArr:[Int] = [11, 44, 55, 77, 88, 22] // Accessing the element present at index 3 // Using subscript syntax print(“Array element:”, someArr[3]) Output When the above code is compiled and executed, it produces the following result − Array element: 77 Using subscript syntax, we can also modify the elements of the array by assigning new value to the existing index. Example import Foundation // Defining and initializing an array var someArr:[Int] = [11, 44, 55, 77, 88, 22] // Modifying the array element present at index 3 // Using subscript syntax someArr[3] = 33 print(“Modified Array element:”, someArr[3]) Output When the above code is compiled and executed, it produces the following result − Modified Array element: 33 Adding a New Element in an Array in Swift We are allowed to add new elements to the existing array using the following methods. Using append() Method It adds a new element at the end of the specified array. Example import Foundation // Defining and initializing an array var someArr:[Int] = [43, 32, 11] // Appending new element using append() method someArr.append(34) someArr.append(60) print(“Updated Array”, someArr) Output When the above code is compiled and executed, it produces the following result − Updated Array [43, 32, 11, 34, 60] Using the addition assignment operator (+=) We can also add a new item at the end of an array using the addition assignment operator. Example import Foundation // Defining and initializing an array var someArr:[Int] = [43, 32, 11] // Adding new element using += operator someArr += [30] someArr += [90] print(“Updated Array”, someArr) Output When the above code is compiled and executed, it produces the following result − Updated Array [43, 32, 11, 30, 90] Iterating Over an Array in Swift Iterating over an array is the fundamental and most commonly used operation in programming. It allows the developer to access and process individual elements of the specified array. In Swift, we can iterate over an array using the following methods − Using for-in loop We can use a for-in loop to iterate over the entire set of values in an array. It is the easiest and cleanest method to access and process each element of the given array sequentially. Example import Foundation // Defining and initializing an array var someArr:[Int] = [3, 56, 12, 4, 23, 5, 6, 7, 8] print(“Array Elements:”) // Iterating over the array using a for-in loop for x in someArr{ print(x) } Output When the above code is compiled and executed, it produces the following result − Array Elements: 3 56 12 4 23 5 6 7 8 Using the enumerated() function with for-in loop We can also use the
Swift – Inheritance
Swift – Inheritance ”; Previous Next Inheritance is the most commonly used feature of object-orientated programming, it allows a class (subclass or derived class) can inherit methods, properties and functionalities from another class (base class or superclass). It provides a mechanism to organize and reuse code. It is also used to create a hierarchical relationship between classes. Swift also provides access control modifiers to control the visibility of properties and methods in base and sub-classes. In Swift, classes can be further categorized into sub-class and super-class − Sub Class − when a class inherits properties, methods and functions from another class it is called a subclass or derived class. Super Class − A class containing properties, methods and functions to inherit other classes from itself is called as a superclass or base class. Base Class A class that does not inherit methods, properties or functions from another class is known as the Base Class. Or we can say that the base class is a foundational class for other classes that derive from it. A base class is also known as a superclass. It provides a set of methods, properties, and behaviour that can be shared among its subclasses. A base class is defined just like a regular class, which means using a class keyword. Syntax Following is the syntax of the base class − class BaseClassName{ // Properties // Methods } Example Swift program to demonstrate how to create a base class. // Base class class StudDetails { // Properties var stname: String var mark1: Int var mark2: Int var mark3: Int // Initializer init(stname: String, mark1: Int, mark2: Int, mark3: Int) { self.stname = stname self.mark1 = mark1 self.mark2 = mark2 self.mark3 = mark3 } } // Instance of the base class let stObj = StudDetails(stname: “Swift”, mark1: 98, mark2: 89, mark3: 76) // Accessing the Properties print(stObj.stname) print(stObj.mark1) print(stObj.mark2) print(stObj.mark3) Output It will produce the following output − Swift 98 89 76 Subclass A class is created from the base class or an existing class is known as a subclass. A subclass inherits the methods and properties of the base class and can also have its own properties and methods. It can also override the properties and methods inherited from the superclass. A subclass can also have subclasses, they inherit or override the properties and methods of both the immediate base class(subclass) and base class, and also have their own additional properties and methods. A subclass is defined by using a class keyword followed by the name of the subclass, a colon and the name of the base class from which it will derive. In a subclass, we have to use super.init in the subclass’s initializer to make sure that the initialization code from the base class will execute before the initialization code of the subclass. Syntax Following is the syntax of the subclass − class SubClassName : BaseClassName{ // Properties // Methods } Example Swift program to demonstrate subclass. // Base Class class StudDetails { // Properties var name: String var age: Int var className: String // Initializer init(name: String, age: Int, className: String) { self.name = name self.age = age self.className = className } // Method func Show() { print(“Name: (name), Age: (age), className: (className)”) } } // Sub class class Marks: StudDetails{ // Properties var mark1: Int var mark2: Int // Initializer init(mark1: Int, mark2: Int, name: String) { self.mark1 = mark1 self.mark2 = mark2 // This Initializer will execute before the Initializer of sub-class super.init(name: name, age: 18, className: “3rd”) } // Overriding method of base class override func Show() { print(“Mark1: (mark1) and Mark2: (mark2)”) } } // Creating an instance of a subclass let obj = Marks(mark1: 23, mark2: 45, name: “Mohita”) // Accessing the method obj.Show() // Accessing the properties of the base class using the subclass instance print(“Name:”, obj.name) print(“Age:”, obj.age) Output It will produce the following output − Mark1: 23 and Mark2: 45 Name: Mohita Age: 18 Type of Inheritance Swift supports the following type of inheritance − Single Multilevel Hierarchical Swift class does not support multiple inheritance to avoid some complexities and challenges such as diamond problems, increased coupling, and initialization challenges. But we can achieve multiple inheritance using Protocols. Single Inheritance A single inheritance is an inheritance where a class is derived from only one superclass and a subclass can access all the properties and methods of the superclass. For example, Class Y is derived from Class X. Example Swift program to demonstrate single inheritance. // Base Class class Employee { // Properties var name: String var age: Int // Initializer init(name: String, age: Int) { self.name = name self.age = age } // Method func Show() { print(“Name: (name), Age: (age)”) } } // Subclass class EmpDetails: Employee{ // Properties var department: String var salary: Int var joiningYear: Int // Initializer init(department: String, salary: Int, joiningYear: Int) { self.department = department self.salary = salary self.joiningYear = joiningYear // Calling superclass initializer super.init(name: “Rohit”, age: 23) } // Method func Display() { print(“Department: (department), Salary: (salary), and Joining Year: (joiningYear)”) } } // Creating an instance of a subclass let obj = EmpDetails(department: “HR”, salary: 23000, joiningYear: 2021) // Accessing the method of superclass obj.Show() // Accessing the methods of the subclass obj.Display() Output It will produce the following output − Name: Rohit, Age: 23 Department: HR, Salary: 23000, and Joining Year: 2021 Multi-level Inheritance A multi-level inheritance refers to an inheritance where a class