Contents
Swift OOPs
Swift Structures
A structure in Swift is a general-purpose building block used to group variables of different data types into a single unit. Similar to other programming languages, Swift allows defining properties (constants or variables) and methods inside a structure. Unlike classes, structures are value types in Swift, meaning their values are copied when assigned to variables, constants, or passed to functions. Structures are useful for encapsulating data and related functionality.
Syntax
struct StructureName {
// Properties and methods
}
Example 1: Creating a Structure
// Swift program to illustrate how to create a structure
import Swift
// Defining a structure
struct Employee {
var name = "Mohit"
var id = 1234
var department = "HR"
var joiningYear = 2019
}
Structure Instances
Instances of structures allow access to their properties and methods. They can be created using the initializer syntax.
// Creating an instance of the structure
let employeeInstance = Employee()
Example 2: Accessing Structure Properties:
// Swift program to demonstrate property access
import Swift
// Defining a structure
struct Employee {
var name = "Mohit"
var id = 1234
var department = "HR"
var joiningYear = 2019
}
// Creating an instance
let employeeInstance = Employee()
// Accessing properties
print("Employee Name:", employeeInstance.name)
print("Joining Year:", employeeInstance.joiningYear)
Output:
Employee Name: Mohit
Joining Year: 2019
Memberwise Initializers
Structures in Swift automatically generate a memberwise initializer, which can be used to set property values when creating an instance.
// Swift program demonstrating memberwise initializers
import Swift
// Defining a structure
struct Employee {
var name = "Mohit"
var id = 1234
var department = "HR"
var joiningYear = 2019
}
// Using memberwise initializer
let updatedEmployee = Employee(id: 5678)
print("Updated Employee ID:", updatedEmployee.id)
Output:
Updated Employee ID: 5678
Example 3: Using Functions Inside a Structure
Structures can include functions, referred to as methods.
// Swift program demonstrating a method in a structure
import Swift
// Defining a structure
struct Salary {
var baseSalary = 230000
func calculateIncrement() {
let newSalary = 2 * baseSalary
print("New Salary:", newSalary)
}
}
// Creating an instance
let salaryInstance = Salary()
// Calling the method
salaryInstance.calculateIncrement()
Output:
New Salary: 460000
Using self
in a Structure
The self
keyword is used to reference the current instance of a structure, especially when parameter names overlap with property names.
Example:
// Swift program demonstrating the use of self keyword
import Swift
// Defining a structure
struct Article {
var count = 230
func update(count: Int = 23) {
let updatedData1 = count + 234
print("Updated Data 1:", updatedData1)
// Using self to reference the property
let updatedData2 = self.count + 234
print("Updated Data 2:", updatedData2)
}
}
// Creating an instance
let articleInstance = Article()
// Calling the method
articleInstance.update()
Output:
Updated Data 1: 257
Updated Data 2: 464
Swift Properties and its Different Types
In Swift, properties associate values with a class, structure, or enumeration. They are categorized into stored properties and computed properties:
- Stored Properties store constant or variable values as part of an instance.
- Computed Properties calculate a value, rather than storing it, using custom getter and setter methods.
Stored Properties
Stored properties are directly stored within an instance of a type and can either be variable (var
) or constant (let
).
1. Variable Stored Properties
Example:
// Swift program for variable stored properties
// Creating a structure
struct Person {
// Stored property
var name: String
}
// Creating a Person instance
let person = Person(name: "John")
// Accessing the property
print("The person's name is \(person.name)")
Output:
The person's name is John
2. Constant Stored Properties
Example:
// Swift program for constant stored properties
// Creating a structure
struct Employee {
// Constant stored properties
let age: Int
let name: String
}
// Creating an Employee instance
let employee = Employee(age: 30, name: "Jane")
// Accessing the properties
print("The employee's name is \(employee.name)")
print("The employee's age is \(employee.age)")
Output:
The employee's name is Jane
The employee's age is 30
Lazy Stored Properties
Lazy stored properties defer their initialization until they are first accessed. Use the lazy
keyword to declare such properties.
Example:
// Swift program for lazy stored property
// Class containing a lazy property
class Course {
var courseName: String?
// Lazy property
lazy var description: String = {
guard let name = self.courseName else { return "No course available" }
return "Course: \(name)"
}()
init(courseName: String) {
self.courseName = courseName
}
}
// Using the class
var course = Course(courseName: "Swift")
print(course.description)
Output:
Course: Swift
Computed Properties
Computed properties calculate a value using a custom getter (and optionally, a setter). They do not store values directly.
Example:
// Swift program for computed properties
// Structure
struct Rectangle {
var length: Double
var width: Double
// Computed property
var perimeter: Double {
get {
return 2 * (length + width)
}
set(newPerimeter) {
length = (newPerimeter - width) / 2
}
}
}
var rect = Rectangle(length: 10, width: 5)
// Accessing the computed property
print("Perimeter: \(rect.perimeter)")
// Modifying the property
rect.perimeter = 40
// Accessing updated property
print("Length: \(rect.length)")
Output:
Perimeter: 30.0
Length: 17.5
Read-Only Computed Properties
A read-only computed property has only a getter and no setter.
Example:
// Swift program for read-only computed property
// Structure to calculate the volume of a cuboid
struct Cuboid {
var width: Double
var height: Double
var depth: Double
// Read-only computed property
var volume: Double {
return width * height * depth
}
}
// Using the structure
let cuboid = Cuboid(width: 4.0, height: 4.0, depth: 4.0)
print("The volume is \(cuboid.volume)")
Output:
The volume is 64.0
Property Observers
Property observers are methods triggered automatically whenever a property’s value is about to be or has just been changed. Use willSet
and didSet
for observing property changes.
Example:
// Swift program for property observers
// Class to track steps
class StepCounter {
var totalSteps: Int = 0 {
willSet(newTotalSteps) {
print("About to set total steps to \(newTotalSteps)")
}
didSet {
if totalSteps > oldValue {
print("Added \(totalSteps - oldValue) new steps")
}
}
}
}
// Using the class
let counter = StepCounter()
counter.totalSteps = 105
counter.totalSteps = 240
counter.totalSteps = 370
Output:
About to set total steps to 105
Added 105 new steps
About to set total steps to 240
Added 135 new steps
About to set total steps to 370
Added 130 new steps
Swift Methods
Methods are functions tied to specific types like classes, structures, and enumerations. They are broadly classified into instance methods, which perform tasks specific to an instance, and type methods, which are called on the type itself. Swift distinguishes itself from Objective-C by allowing methods to be defined in structures and enumerations, not just classes.
Instance Methods
Instance methods define behavior that acts on an instance of a type, enabling access to or modification of the instance’s properties.
Syntax
func methodName(parameters) -> ReturnType {
// Code block
return value
}
Example:
class Calculator {
let x: Int
let y: Int
let result: Int
init(x: Int, y: Int) {
self.x = x
self.y = y
self.result = x + y
}
func subtract(by value: Int) -> Int {
return result - value
}
func displayResults() {
print("Result after subtraction: \(subtract(by: 50))")
print("Result after subtraction: \(subtract(by: 100))")
}
}
let calculator = Calculator(x: 200, y: 300)
calculator.displayResults()
Output:
Result after subtraction: 450
Result after subtraction: 400
Local and External Parameter Names
Swift methods provide flexibility with parameter names by allowing both local and external parameter names. This helps improve code readability.
Example:
class Divider {
var quotient: Int = 0
func divide(_ numerator: Int, by denominator: Int) {
quotient = numerator / denominator
print("Quotient is: \(quotient)")
}
}
let divider = Divider()
divider.divide(120, by: 3)
divider.divide(180, by: 6)
Output:
Quotient is: 40
Quotient is: 30
Self
Keyword in Methods
The self
keyword refers to the current instance of a class, structure, or enumeration within its methods.
Example:
class Calculator {
let x: Int
let y: Int
let result: Int
init(x: Int, y: Int) {
self.x = x
self.y = y
self.result = x + y
print("Inside initializer: \(result)")
}
func subtract(by value: Int) -> Int {
return result - value
}
func showResults() {
print("Subtraction result: \(subtract(by: 20))")
print("Subtraction result: \(subtract(by: 30))")
}
}
let calc1 = Calculator(x: 100, y: 200)
calc1.showResults()
Output:
Inside initializer: 300
Subtraction result: 280
Subtraction result: 270
Modifying Value Types with Instance Methods
Structures and enumerations, as value types, cannot modify their properties in normal instance methods. However, using the mutating
keyword allows methods to modify properties.
Example
struct Rectangle {
var length = 1
var width = 1
func area() -> Int {
return length * width
}
mutating func scale(by factor: Int) {
length *= factor
width *= factor
print("Scaled dimensions: Length = \(length), Width = \(width)")
}
}
var rectangle = Rectangle(length: 4, width: 5)
rectangle.scale(by: 2)
rectangle.scale(by: 3)
Output:
Scaled dimensions: Length = 8, Width = 10
Scaled dimensions: Length = 24, Width = 30
Type Methods
Type methods operate on the type itself rather than its instances. Use the class
keyword for type methods in classes and the static
keyword for structures and enumerations.
Example
class MathOperations {
class func absoluteValue(of number: Int) -> Int {
return number < 0 ? -number : number
}
}
struct Utility {
static func absoluteValue(of number: Int) -> Int {
return number < 0 ? -number : number
}
}
let absValueClass = MathOperations.absoluteValue(of: -10)
let absValueStruct = Utility.absoluteValue(of: -20)
print("Class absolute value: \(absValueClass)")
print("Struct absolute value: \(absValueStruct)")
Output:
Class absolute value: 10
Struct absolute value: 20
Difference Between Function and Method
Functions vs. Methods in Swift
While some people use the terms “function” and “method” interchangeably, they have distinct meanings in Swift. Both perform specific tasks and can be reused, but methods are inherently tied to types like classes, structures, or enumerations, while functions are not.
In short, a method is a function that is associated with a type. All methods are functions, but not all functions are methods. Swift uses the func
keyword to define both functions and methods.
Functions
A function is a standalone block of code that performs a specific task. Functions can be defined globally and are not associated with any type. They can accept parameters, perform actions, and return results. Functions are independent and can be used anywhere in a program.
Syntax:
func functionName(parameters) -> ReturnType {
// Body of the function
}
Example:
// Swift program to illustrate a function
// Function
func greet() {
print("Hello Swift!")
}
// Calling the function
greet()
Output:
Hello Swift!
Methods
A method is a function associated with a type, such as a class, struct, or enum. Methods can be of two types:
1. Instance Methods: Called on instances of a type.
2. Type Methods: Called on the type itself and are prefixed with static or class.
Syntax:
func methodName(parameters) {
// Body of the method
}
Example:
// Swift program to illustrate methods
struct Developer {
let speed: Int
// Instance method
func learn() {
print("Learning at \(speed) MPH")
}
// Type method
static func code() {
print("Writing Swift code")
}
}
// Create an instance
let dev = Developer(speed: 15)
// Call instance method
dev.learn()
// Call type method
Developer.code()
Output:
Learning at 15 MPH
Writing Swift code
Difference Between Functions and Methods
Aspect | Function | Method |
---|---|---|
Existence | Functions are independent and can be defined outside of a class, struct, or enum. | Methods are always associated with a class, struct, or enum. |
Reference | Functions do not have reference variables. | Methods are accessed using reference variables or instances of a type. |
Usage | Functions are called directly. | Methods are called using an instance or the type name. |
Property | Functions are part of structured programming languages. | Methods are properties of object-oriented programming languages. |
Purpose | Functions are self-contained pieces of code. | Methods often manipulate instance variables of the type they belong to. |
Association | Functions are not tied to any type. | Methods are tied to a specific class, struct, or enum. |
Relationship | Not every function is a method. | Every method is a function. |
Swift – Deinitialization and How It Works
Deinitialization in Swift is the process of releasing memory allocated to an instance when it is no longer needed. When a class instance is no longer in use, deinitialization ensures that its memory is freed up for other purposes. This process helps improve memory management by cleaning up unused objects in the system.
Deinitialization is primarily used with class types and is triggered automatically before an instance is deallocated. Swift uses the deinit
keyword to define a deinitializer. A class can have only one deinitializer, and it does not accept parameters or return values. You can include custom cleanup code within the deinitializer to perform tasks like releasing resources or saving data.
Syntax:
deinit {
// Code for deinitialization actions
}
Example:
// Swift program to store values in arrays
// Initializing an array of integer type
var numbers: [Int] = [1, 3, 5, 7]
// Initializing another array of character type
var characters: [Character] = ["A", "B", "C", "D"]
// Print arrays
print("Numbers Array: \(numbers)")
print("Characters Array: \(characters)")
Output:
Value of x before deinit = 20
Value of x after deinit = 0
How Deinitialization Works
Swift employs Automatic Reference Counting (ARC) to manage memory. When an instance is no longer required, Swift automatically deallocates it, freeing up memory resources. This automated process eliminates the need for manual cleanup, ensuring efficient memory management.
Deinitializers are automatically called just before an instance is deallocated. Subclasses inherit their superclass’s deinitializers, and the superclass’s deinitializer is called after the subclass’s implementation completes. Even if a subclass does not define its own deinitializer, the superclass’s deinitializer will still be invoked.
If memory is not released as expected after a deinitializer is executed, it may be due to properties still referencing the instance, preventing deallocation. In such cases, deinitializers can modify these properties to allow memory release.
Example 1: Basic Deinitialization
In the following example, a variable x
is initialized to 10. During the class’s initialization, x
is incremented by 10. The value of x
is then printed, and the class object is set to nil
. This triggers the deinitializer, which resets x
to 0.
// Swift program to illustrate deinitialization
// Initialize a variable x with value 10
var x = 10
// Create a class
class DeinitializerExample {
// Initialization
init() {
x += 10
}
// Deinitialization: Set x to 0
deinit {
x = 0
}
}
// Create an instance of the class
var obj: DeinitializerExample? = DeinitializerExample()
print("Value of x before deinit = \(x)")
// Trigger deinitialization
obj = nil
print("Value of x after deinit = \(x)")
Output:
Value of x before deinit = 20
Value of x after deinit = 0
Typecasting in Swift
Typecasting in Swift is a way to determine and change the type of an instance of a class, structure, or enumeration. When dealing with objects of different types, typecasting enables runtime type checking and allows safe downcasting to subclass types.
Swift provides two types of typecasting:
1. Upcasting: Converting a subclass instance to its superclass, which is always safe.
2. Downcasting: Converting a superclass instance to its subclass, which requires explicit syntax as it’s not always safe.
Swift provides two main operators for typecasting:
is
operator: Checks if an instance belongs to a specific subclass type.as
operator: Attempts to cast an instance to a subclass type and returns an optional value.
Upcasting
Upcasting refers to converting a subclass instance to its superclass. This is always safe and does not require explicit syntax.
Example:
class Animal {
var name: String
init(name: String) {
self.name = name
}
func makeSound() {
print("Animal sound")
}
}
class Dog: Animal {
override func makeSound() {
print("Woof")
}
}
let dog = Dog(name: "Fido")
let animal: Animal = dog // Upcasting
print(animal.name)
animal.makeSound()
Output:
Fido
Woof
Type Checking with is
Operator
The is
operator checks whether an instance is of a specific type.
Example:
let myInstance: Any = 42
if myInstance is Int {
print("myInstance is an Int")
} else {
print("myInstance is not an Int")
}
Output:
myInstance is an Int
Type Casting with as?
and as!
as?
: Safely attempts to cast an instance, returning an optional.as!
: Forcefully casts an instance, causing a runtime error if it fails.
Example:
class Vehicle {
var name: String
init(name: String) {
self.name = name
}
}
class Car: Vehicle {
var brand: String
init(name: String, brand: String) {
self.brand = brand
super.init(name: name)
}
}
let myVehicle = Car(name: "My Car", brand: "Tesla")
let myCar = myVehicle as? Car
if let myCar = myCar {
print("My car's brand is \(myCar.brand)")
} else {
print("myVehicle is not a Car")
}
Output:
My car's brand is Tesla
Any and AnyObject
Any
: Represents any type, including functions and optionals.AnyObject
: Represents any class type.
Example:
let myInstance: Any = 42
if let myInt = myInstance as? Int {
print("myInt is \(myInt)")
}
struct Car {
var name: String
var brand: String
}
let myObject = Car(name: "My Car", brand: "Tesla")
print("My car's name is \(myObject.name)")
Output:
myInt is 42
My car's name is My Car
Type Erasure
Type erasure hides the concrete type of an object while providing a uniform interface.
Example:
protocol Printable {
func printMe()
}
class Car: Printable {
func printMe() {
print("I'm a Car")
}
}
class Dog: Printable {
func printMe() {
print("I'm a Dog")
}
}
struct PrintableBox {
let value: T
func printValue() {
value.printMe()
}
}
let myCar = Car()
let box = PrintableBox(value: myCar)
box.printValue()
Output:
I'm a Car
Repeating Timers in Swift
In Swift, an array is an ordered collection that stores values of the same type. For example, an array declared to hold integers cannot store floating-point numbers. Arrays in Swift can store duplicate values.
When an array is assigned to a variable, it is mutable, meaning you can modify its contents and size. However, when an array is assigned to a constant, it becomes immutable, and you cannot modify it.
Removing Elements in Swift Arrays
You can remove the first element from a Swift array using the removeFirst()
function. Additionally, you can use this function to remove multiple elements from the start of the array by specifying the number of elements to remove as an argument.
Syntax
arrayName.removeFirst(x: Int)
Example 1: Removing a Single Element
import Swift
// String array of authors' names
var authors = ["Alice", "Bob", "Charlie", "Diana", "Eve"]
print("Authors before removing the first element: \(authors)")
// Remove the first element
authors.removeFirst()
print("Authors after removing the first element: \(authors)")
// Integer array of article IDs
var articleIDs = [101, 202, 303, 404, 505]
print("\nArticle IDs before removing the first element: \(articleIDs)")
// Remove the first element
articleIDs.removeFirst()
print("Article IDs after removing the first element: \(articleIDs)")
Output:
Authors before removing the first element: ["Alice", "Bob", "Charlie", "Diana", "Eve"]
Authors after removing the first element: ["Bob", "Charlie", "Diana", "Eve"]
Article IDs before removing the first element: [101, 202, 303, 404, 505]
Article IDs after removing the first element: [202, 303, 404, 505]
Repeating Timers in Swift
A repeating timer is a mechanism that schedules code to run at regular intervals. It continues until explicitly stopped. Repeating timers are helpful in scenarios requiring periodic execution, such as polling or periodic updates.
Creating a Repeating Timer
Steps:
1. Create a Timer Object: Use Timer.scheduledTimer
to create the timer.
- timeInterval: Time (in seconds) between repetitions.
- target: Object that receives the method call when the timer fires.
- selector: Method called when the timer fires.
- userInfo: Optional data passed to the method.
2. Start the Timer: Call the fire() method on the timer.
3. Implement the Timer Method: Write the method to be executed each time the timer fires.
Example:
class TimerExample {
var timer: Timer?
func startTimer() {
timer = Timer.scheduledTimer(timeInterval: 2.0, target: self, selector: #selector(timerFired), userInfo: nil, repeats: true)
timer?.fire()
}
func stopTimer() {
timer?.invalidate()
timer = nil
}
@objc func timerFired() {
print("Timer fired!")
}
}
let example = TimerExample()
example.startTimer()
Output:
Timer fired!
Timer fired!
Timer fired!
... (repeats every 2 seconds)
Invalidating a Timer
To stop a timer, use the invalidate()
method. This prevents further firing of the timer.
Example:
example.stopTimer()
The timer stops firing.
Scheduling a Timer on a Background Thread
By default, timers are scheduled on the main thread. Use Timer.scheduledTimer(withTimeInterval:repeats:block:)
for background execution.
Example:
let queue = DispatchQueue.global(qos: .background)
let timer = Timer.scheduledTimer(withTimeInterval: 2.0, repeats: true) { _ in
print("Timer fired!")
}
queue.async {
RunLoop.current.add(timer, forMode: .default)
RunLoop.current.run()
}
Output:
Timer fired!
Timer fired!
Timer fired!
... (on a background thread)
Rescheduling a Timer
To change a timer’s interval, invalidate the existing timer and create a new one.
Example:
class ReschedulingTimerExample {
var timer: Timer?
var timeInterval: TimeInterval = 2.0
func startTimer() {
timer = Timer.scheduledTimer(timeInterval: timeInterval, target: self, selector: #selector(timerFired), userInfo: nil, repeats: true)
timer?.fire()
}
func rescheduleTimer(newInterval: TimeInterval) {
timer?.invalidate()
timeInterval = newInterval
startTimer()
}
@objc func timerFired() {
print("Timer fired!")
}
}
let rescheduleExample = ReschedulingTimerExample()
rescheduleExample.startTimer()
rescheduleExample.rescheduleTimer(newInterval: 5.0)
Output:
Timer fired! (every 2 seconds initially)
Timer fired! (every 5 seconds after rescheduling)
Using GCD Timers
GCD timers offer an efficient way to schedule tasks.
Example:
let queue = DispatchQueue.global(qos: .background)
let timer = DispatchSource.makeTimerSource(queue: queue)
timer.schedule(deadline: .now(), repeating: .seconds(2))
timer.setEventHandler {
print("Timer fired!")
}
timer.resume()
Output:
Timer fired!
Timer fired!
Timer fired!
... (repeats every 2 seconds)
Non Repeating Timers in Swift
Developers can create effective and efficient applications using Swift, a versatile and powerful programming language. Among its many tools, the Timer class is particularly useful for defining timed events that run at specified intervals. This post will discuss how to create and manage non-repeating timers using Swift’s Timer class.
Swift timers are commonly used for scheduling tasks with a delay or for creating repeating jobs. The Timer class, previously known as NSTimer
, provides a flexible mechanism for scheduling tasks either once or periodically.
Importing Foundation
Since the Timer class is part of the Foundation framework, you need to import it to use timers in your application:
import Foundation
Why Use Timers?
Timers are useful in scenarios where you need to execute specific actions after a set period or repeatedly within a specified time frame. Some common use cases include:
Automatically calling a method every 5 seconds.
Sending a local notification on app termination.
Syncing cart details with a backend server after a specified interval.
The Basics: scheduledTimer
The scheduledTimer
method is used to create a timer. It requires you to specify parameters such as timeInterval
, selector
, and repeats
.
timeInterval
: Specifies the number of seconds before the timer fires.selector
: The function to be invoked when the timer fires.repeats
: A boolean that determines whether the timer fires repeatedly.
Example:
/// Create an empty timer variable
var timer = Timer()
// In a function or viewDidLoad()
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)
// Define the action for the timer
@objc func timerAction() {
print("Timer fired!")
}
Output:
Timer fired!
Timer fired!
Timer fired!
... (repeats every 1 second)
Parameters Explanation
When creating a timer, five key parameters are required:
- timeInterval: The time in seconds between timer firings.
- target: The object on which the selector method is called.
- selector: The method to execute when the timer fires.
- userInfo: Optional data passed to the selector.
- repeats: Specifies whether the timer should fire repeatedly.
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timerAction), userInfo: nil, repeats: false)
You can stop a repeating timer manually by calling .invalidate()
:
Example:
@objc func timerAction() {
print("Timer fired once!")
timer.invalidate()
}
Output:
Timer fired once!
Repeating vs. Non-Repeating Timers
Non-Repeating Timer: Fires once and invalidates itself automatically.
Repeating Timer: Fires repeatedly at the specified interval and continues until manually invalidated.
Creating a Non-Repeating Timer
Example:
let timer = Timer.scheduledTimer(timeInterval: 5.0, target: self, selector: #selector(fireOnce), userInfo: nil, repeats: false)
@objc func fireOnce() {
print("Firing the function after a specific interval")
}
Output:
Timer fired once!
Parameters Explanation
When creating a timer, five key parameters are required:
- timeInterval: The time in seconds between timer firings.
- target: The object on which the selector method is called.
- selector: The method to execute when the timer fires.
- userInfo: Optional data passed to the selector.
- repeats: Specifies whether the timer should fire repeatedly.
Example:
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timerAction), userInfo: nil, repeats: false)
@objc func timerAction() {
print("Timer fired once!")
timer.invalidate()
}
Output:
Timer fired once!
Repeating vs. Non-Repeating Timers
- Non-Repeating Timer: Fires once and invalidates itself automatically.
- Repeating Timer: Fires repeatedly at the specified interval and continues until manually invalidated.
Creating a Non-Repeating Timer
Example:
let timer = Timer.scheduledTimer(timeInterval: 5.0, target: self, selector: #selector(fireOnce), userInfo: nil, repeats: false)
@objc func fireOnce() {
print("Firing the function after a specific interval")
}
Output:
Firing the function after a specific interval
Example Scenarios
Example 1: Display a Message After a Delay
let timer = Timer.scheduledTimer(withTimeInterval: 5, repeats: false) { _ in
print("Time's up!")
}
Output:
Time's up!
Timer Tolerance
Adding a tolerance can improve power efficiency. Tolerance specifies how much later the timer can fire, which helps conserve resources, especially in background operations.
Example:
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)
timer.tolerance = 0.3