Our Global Presence
Canada
57 Sherway St,
Stoney Creek, ON
L8J 0J3
India
606, Suvas Scala,
S P Ring Road, Nikol,
Ahmedabad 380049
USA
1131 Baycrest Drive,
Wesley Chapel,
FL 33544
On the 25th of March Apple announced that the release process for Swift 5.3 has begun, it’s a major change since it will improve the overall language quality and performance, and will make Swift available for multiple platforms as Windows and Linux. But let’s see in detail whats new.
Currently a class extending a protocol needs to match exactly the protocol’s requirements, for example if we write static requirements within a protocol:
protocol DecodingError { static var fileCorrupted: Self { get } static func keyNotFound(_ key: String) -> Self }
And then we try to conform an enum to our protocol, we’ll face the following error:
With SE-0280 this will no longer cause a compiling error.
Swift 5.3 finally introduced the possibility to use multiple trailing closures.
First of all for those who don’t know what a trailing closure is, it’s a simple syntactic sugar that we can use when we have a closure parameter in a function:
func networkCall(parameter:Int, onSuccess:(Any)->Void) { //network call onSuccess("someNetworkResult") }
and we can simply call the function as follows:
networkCall(parameter: 1) { (result) in print(result) }
This is an amazing feature and allows us to write cleaner and easier to read code, however it’s currently limited only to the last parameter of a function as we can see in the following example:
With SE-0279 we will be allowed to insert extra trailing closures, just by adding extra labels, therefore the following code will compile.
networkCall(parameter: 1){(progress) in print(progress) }, onSuccess{ (result) in print(result) }
The last decade has seen a dramatic increase in the use of floating-point types smaller than (32-bit) Float. The most widely implemented is Float16, which is used extensively on mobile GPUs for computation, as a pixel format for HDR images, and as a compressed format for weights in ML applications. Introducing the type to Swift is especially important for interoperability with shader-language programs; users frequently need to set up data structures on the CPU to pass to their GPU programs. Without the type available in Swift, they are forced to use unsafe mechanisms to create these structures.
Currently swift allows only a single error type for each catch clause, that means that if we define the following enum
enum NetworkError: Error { case timeout, serverError }
Assuming someNetworkCall is a function that throws a NetworkError, and we want to handle both errors, we will need to write two separate catch clauses:
func networkCall(){ do{ try someNetworkCall() }catch NetworkError.timeout{ print("error") }catch NetworkError.serverError{ print("error") } }
With SE-0276 we will be allowed to handle both errors on a single catch clause, with the following code:
func networkCall(){ do{ try someNetworkCall() }catch NetworkError.timeout, NetworkError.serverError{ print("error") } }
Currently we can use Range to refer to multiple consecutive positions in a Collection, but there’s not a simple way to do this for discontiguous positions, based on some condition.
For example if we have an array of numbers from 0 to 15 and we want to get a sub range of the Array, let’s say with only even numbers, the language doesn’t provide any way to get it, or even to get a sub Array with elements with non contiguous positions, but we can only select a range of contiguous elements:
SE-0270 adds a super useful “RangeSet” Method that will allow us to get a subRange of all the indexes of the elements that satisfy a specific condition, therefore, if we want to get only even numbers from the previous array, the following code will work:
var numbers = Array(1...15) // Find the indices of all the even numbers let indicesOfEvens = numbers.subranges(where: { $0.isMultiple(of: 2) }) // Perform an operation with just the even numbers let sumOfEvens = numbers[indicesOfEvens].reduce(0, +) // sumOfEvens == 56 // You can gather the even numbers at the beginning let rangeOfEvens = numbers.moveSubranges(indicesOfEvens, to: numbers.startIndex) // numbers == [2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15] // numbers[rangeOfEvens] == [2, 4, 6, 8, 10, 12, 14]
Currently in closures we need to use explicit self even in some cases where reference cycles are unlikely to happen, for example because we already captured self in the current closure:
To make our code compile we need to add explicit self to x in order to reference it.
didSet
SemanticsCurrently, if we have a property with a “didSet” observer, the getter to get the oldValue is always called, even if observer doesn’t contain any reference to the oldValue in its body, for example the following code
struct Container { var items: [Int] = .init(repeating: 1, count: 100) { //creates an Array of 100 elements didSet { print("value set")//oldValue never Accessed } } mutating func update() { for index in 0..<items.count { items[index] = index + 1 } } } var container = Container() container.update()
creates 100 copies of the array in the memory to provide the oldValue
, even though they’re not used at all, causing performance issues.
With SE-0268 the property getters will be no longer called if they’re not accessed within the didSet resulting in a performance boost.
class Foo { var bar = 0 { didSet { print("didSet called") } } var baz = 0 { didSet { print(oldValue) } } } let foo = Foo() // This will not call the getter to fetch the oldValue foo.bar = 1 // This will call the getter to fetch the oldValue foo.baz = 2
Where
Clauses on Contextually Generic DeclarationsCurrently a where clause on a member declaration can be used only by placing the member inside a specific extension, but this can sound confusing, let’s make an example.
Let’s say we want to extend the Array implementation to sort element of 3 different types, for which we want to define a different sorting logic.
Currently we would need to extend Array 3 times:
extension Array where Element == String { func sortStrings() { ... } //some specific sorting logic } extension Array where Element == Int { func sortInts() { ... } //some specific sorting logic } extension Array where Element: Equatable { func sort() { ... } //some specific sorting logic }
With SE-0267 we can implement that logic by simply adding the where clause to the function in a single extension:
extension Array where Element: Equatable { func sort() { ... } func sortInts() where Element == Int { ... } func sortStrings() where Element == String { ... } }
Comparable
Conformance for Enum TypesLet’s say we want to define an Enum whose cases have an obvious semantic order, for example:
enum SchoolGrades { case F case E case D case C case B case A }
If we try to compare its values we got the following error:
In order to compare two Objects, they need to conform the Comparable protocol:
looking at the warning this will generate a loop, since the < function will be calling itself, therefore we need to compare the rawValues so that we can finally compare our grades.
This, is just a simple case, and it adds a lot of boilerplate code.
With SE-0266 this will not be necessary and we don’t need any additional code to compare Enums.
For more information and to build a mobile APP using iOS, Hire iOS Developer from us as we give you a high-quality product by utilizing all the latest tools and advanced technology. E-mail us any clock at – hello@hkinfosoft.com or Skype us: “hkinfosoft”. To develop your mobile APP using iOS, please visit our technology page.
Content Source:
57 Sherway St,
Stoney Creek, ON
L8J 0J3
606, Suvas Scala,
S P Ring Road, Nikol,
Ahmedabad 380049
1131 Baycrest Drive,
Wesley Chapel,
FL 33544
57 Sherway St,
Stoney Creek, ON
L8J 0J3
606, Suvas Scala,
S P Ring Road, Nikol,
Ahmedabad 380049
1131 Baycrest Drive,
Wesley Chapel,
FL 33544
© 2024 — HK Infosoft. All Rights Reserved.
© 2024 — HK Infosoft. All Rights Reserved.
T&C | Privacy Policy | Sitemap