Swift 4.0 vs Swift 3.0 - Diferențe și noi caracteristici
Publicat: 2021-10-05Ziua în care Apple lansează o nouă versiune a cunoscutului limbaj Swift ne-a lovit în sfârșit. La ce să ne așteptăm? În timp ce tremurăm de anticipare, am decis să prezentăm o prezentare minusculă a actualizărilor proaspete care vor fi prezente în versiunea Swift 4 .
3 pietrele de temelie ale lui Swift.
Fiind un limbaj fantastic pe care să scrie cod, Swift are propriile sale avantaje și se pretinde că „supraviețuiește” limbajului Objective-C.
Puteți citi despre principalele diferențe dintre Swift și Objective-C
Swift este rapid , sigur de tip și foarte expresiv . Ar putea fi folosit pentru a scrie software pe telefoane și tablete, desktopuri și servere - aparent, pe tot ce rulează cod. Vă întâmpină să jucați cu el - cu aplicația Apple Swift Playgrounds pentru a învăța cum să codificați sau folosind Playgrounds în Xcode, veți vedea imediat rezultatele muncii dvs., nu este nevoie să vă lăsați nasul în dezvoltarea și rularea unei aplicații la primul loc. Cu fiecare nouă versiune aditivă devine mai bună și mai rapidă, și acesta este cazul versiunii Swift 4.
Pe locuri fiti gata?
O altă caracteristică excelentă pe care Xcode 9 o are pentru Swift 4 - nu trebuie să vă faceți griji cu privire la viitoarea migrare și veți afla de ce în timp ce citiți acest articol.
Vorbind despre asta, să explorăm pe scurt ce ne oferă bonbons și Swift 4 noile caracteristici din această toamnă.
Noțiuni de bază
Limbajul în sine nu este foarte util fără un IDE la îndemână, care este Xcode în lumea dezvoltatorilor. Puteți descărca cea mai recentă versiune a Xcode 9 din Mac App Store sau de pe pagina Descărcări de pe site-ul dezvoltatorului Apple, dar asigurați-vă că aveți un cont de dezvoltator activ în primul rând. Este destul de stabil, astfel încât să puteți înlocui Xcode 8 cu acesta pentru rutinele zilnice de codare.
De asemenea, puteți instala mai multe versiuni de Xcode folosind xcversion
Dacă începeți un nou proiect - sunteți bine să mergeți. Dar dacă aveți deja un proiect scris în Swift 3.x - trebuie să treceți printr-un proces de migrare.
Vă recomandăm să încercați mai întâi terenul de joacă - pentru a vă obișnui folosind funcții noi.
Veți observa linkuri către propunerile Swift Evolution în formatul „SE -____” în timp ce citiți acest articol.
Migrarea la Swift 4
Migrarea de la o versiune majoră a Swift la următoarea a fost întotdeauna destul de intensă, în special de la Swift 2.x la 3.0. De obicei, durează aproximativ 1-2 zile pe proiect, dar migrarea către Swift 4 este puțin mai ușoară și poate fi transmisă mult mai repede.
Pregătirea înainte de migrație
Xcode 9 acceptă nu numai Swift 4, ci și o versiune de tranziție 3.2, astfel încât proiectul dvs. ar trebui să fie compilat fără dificultăți dure. Acest lucru este posibil, deoarece compilatorul Swift 4 și instrumentul de migrare acceptă ambele versiuni ale limbajului. Puteți specifica diferite versiuni Swift per țintă, acest lucru este foarte util dacă unele biblioteci terțe nu s-au actualizat încă sau dacă aveți mai multe ținte în proiect. Cu toate acestea, nu doar limbajul, ci și SDK-ul are unele modificări, deci este foarte probabil ca unele actualizări să fie aplicate codului dvs., deoarece Apple continuă să ascundă API-urile SDK ...
Instrument de migrare rapidă
Ca întotdeauna, Apple oferă instrument de migrare Swift inclus în Xcode, care poate ajuta la migrarea de la versiunea Swift anterioară. Puteți să-l lansați în Xcode accesând Edit -> Convert -> To Current Swift Syntax ... și selectând ce ținte doriți să convertiți.
Vi se va întreba ce preferință de inferență Objective-C doriți să aplicați:
Deoarece modificările aditive domină în Swift 4, instrumentul de migrare Swift va gestiona majoritatea modificărilor pentru dvs.
CocoaPods
Majoritatea dezvoltatorilor folosesc managerul de dependență CocoaPods pentru proiectele lor, deoarece Managerul de pachete Swift nu este atât de matur pe cât ar putea fi, deși se îmbunătățește foarte repede. După cum sa menționat mai sus, nu toate bibliotecile terță parte au fost actualizate încă la Swift 4, astfel încât ați putea vedea erori în timp ce compilați unele dintre ele. O soluție posibilă pentru rezolvarea acestei probleme este specificarea versiunii Swift 3.2
pentru acele pod-uri care nu au fost încă actualizate prin adăugarea unui script post_install
la Podfile
:
old_swift_3_pods = [ 'PodName1', 'PodName2', ] post_install do |installer| installer.pods_project.targets.each do |target| if old_swift_3_pods.include? target.name target.build_configurations.each do |config| config.build_settings['SWIFT_VERSION'] = '3.2' end end end end
Atunci fugi
pod install
Acum puteți compila pod-uri fără erori.
Să examinăm modificările și completările API-ului Swift 4.
Modificări și adăugiri API
Siruri de caractere
String
se conformează acum protocolului de Collection
datorită propunerii SE-0163. Vă amintiți Swift 1.x?
Nu este nevoie în proprietatea matricei de characters
acum, deoarece puteți itera direct pe String
:
let string = "Hello, Mind Studios!" for character in string { print(character) }
Acest lucru înseamnă, de asemenea, că puteți utiliza orice metode și proprietăți de Collection
pe String
, cum ar fi count
, isEmpty
, map()
, filter()
, index(of:)
și multe altele:
string.count // No more `string.characters.count` string.isEmpty // false let index = string.index(of: " ") // 6 let reversedCollection = "abc".reversed() let reversedString = String(reversedCollection) // "cba" // String filtering let string = "ni123n456iniASijasod! 78a9-kasd aosd0" let numbersString = string.filter { Int(String($0)) != nil } // "1234567890"
Tip Substring
nou
Swift 4 aduce un nou tip de Substring
care reprezintă o subsecvență de String
(așa cum este descris în SE-0163 menționat mai sus).
// Split string into substrings let string = "Hello, Mind Studios!" let parts = string.split(separator: " ") // ["Hello,", "Mind", "Studios!"] type(of: parts.first!) // Substring.Type
Ambele String
și Substring
suportă acum nouă StringProtocol
ceea ce le face aproape identice și interoperabile:
var hello = parts.first! // Concatenate a String onto a Substring hello += " !" // "Hello, !" // Create a String from a Substring let helloDog = String(hello) // "Hello, !"
Notă importantă
SE-0163 are o notă foarte importantă:
Long-term storage of `Substring` instances is discouraged. A substring holds a reference to the entire storage of a larger string, not just to the portion it presents, even after the original string's lifetime ends. Long-term storage of a substring may therefore prolong the lifetime of elements that are no longer otherwise accessible, which can appear to be memory leakage.
Ceea ce înseamnă că Substring
este destinat să fie utilizat ca stocare temporară pentru subsecvența String
. Dacă doriți să îl transmiteți unor metode sau alte clase - convertiți-l mai întâi în String
:
let substring: Substring = ... // Substring let string = String(substring) // String someMethod(string)
Oricum, sistemul de tip Swift vă va ajuta să nu treceți Substring
undeva unde se așteaptă String
(presupunând că nu utilizați StringProtocol
nou ca tip de parametru).
Litere de șiruri multiple
SE-0168 introduce o sintaxă simplă pentru literele șirului cu mai multe linii folosind trei ghilimele duble """
ceea ce înseamnă că majoritatea formatelor de text (cum ar fi JSON sau HTML) sau un anumit text lung pot fi lipite fără a scăpa:
let multilineString = """ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam mattis lorem et leo laoreet fermentum. Mauris pretium enim ac mi tempor viverra et fermentum nisl. Sed diam nibh, posuere non lectus at, ornare bibendum erat. Fusce mattis sem ac feugiat vulputate. Morbi at nunc maximus, vestibulum orci et, dictum neque. Vestibulum vulputate augue ac libero vulputate vestibulum. Nullam blandit et sapien non fermentum. Proin mollis nisl at vulputate euismod. """
Scăparea liniilor noi în literele șirului
SE-0182 adaugă abilitatea de a scăpa de linii noi în literele șirului cu mai multe linii cu o bară inversă la sfârșitul liniei.
let escapedNewline = """ Line 1, Line 2 \ next part of line 2, Line 3 """ print(escapedNewline)
Line 1, Line 2 next part of line 2, Line 3
Suport îmbunătățit Unicode
Swift 4 oferă suport pentru Unicode 9, ceea ce înseamnă că problemele cu numărarea caracterelor Unicode au dispărut:
"".count // 1, in Swift 3: 2 "".count // 1, in Swift 3: 2 "".count // 1, in Swift 3: 2 - person + skin tone "".count // 1, in Swift 3: 4 "".count // 3, in Swift 3: 1
Toate modificările și propunerile implementate evidențiate mai sus (ca multe altele) își iau rădăcinile dintr-un set de caracteristici descrise pe larg, denumit Manifestul String.
Controlul accesului
Swift 3 a adus un element foarte contradictoriu pentru controlul accesului - modificator de acces de fileprivate
care poate fi într-adevăr confuz.
Anterior, modificatorul nivelului de acces private
era folosit pentru a ascunde membrii de tip de alte tipuri, iar membrii privați puteau fi accesați numai prin metode și proprietăți definite la definiția tipului, lăsând deoparte aceleași extensii de tip, deoarece nu puteau accesa acei membri.
fileprivate
ar putea fi folosit pentru a partaja accesul pentru membrii de tip, cum ar fi proprietăți și metode, în același fișier.
De fapt, utilizarea private
dus la o problemă atunci când extensiile de pe un anumit tip nu au acces la membrii acestui tip, astfel încât utilizarea fileprivate
în astfel de circumstanțe a fost o soluție foarte comună, ceea ce a dus la o altă problemă: alte tipuri în același fișier ar putea accesa și acei membri.
Swift 4 pune lucrurile în ordine, permițând extensiilor de tip să acceseze membrii private
de acel tip în același fișier descris în SE-0169:
struct User { private let firstName: String private let lastName: String } extension User: CustomStringConvertible { var description: String { return "User: \(firstName) \(lastName)" } }
Dicționar și Set
Inițializarea Dictionary
cu Sequence
Dictionary
poate fi inițializat cu Sequence
acum, dar nu toate secvențele ar putea fi transmise în acest inițialist, doar cele care conțin tupluri (Key, Value)
, unde Key
este tipul cheie al dicționarului și Value
reprezintă tipul valorii dicționarului:
let stocksIdentifiers = ["AAPL", "GOOGL", "NKE"] let stocksValues = [158.28, 940.13, 53.73] let pairs = zip(stocksIdentifiers, stocksValues) let stocksValuesDict = Dictionary(uniqueKeysWithValues: pairs) // ["GOOGL": 940.13, "NKE": 53.73, "AAPL": 158.28]
Aici funcția zip
creează o pereche ( Tuple
) din 2 secvențe, puteți citi mai multe despre această funcție în documentația Swift Standard Library.
Fuzionarea dicționarelor
Puteți specifica modul în care trebuie tratate cheile duplicate atunci când creați un dicționar dintr-o secvență de Tuple
, trecând o închidere la parametrul uniquingKeysWith
, care este utilizat pentru a combina valorile din 2 chei identice.
Exemplul 1:
let duplicates = [("a", 1), ("b", 5), ("a", 3), ("b", 3)] let dictionary = Dictionary(duplicates, uniquingKeysWith: { (first, _) in return first }) // ["b": 5, "a": 1]
Aici lăsăm prima valoare ignorând toate valorile următoare cu aceeași cheie.
Exemplul 2:
Numărarea de câte ori apare fiecare caracter în șir.
let string = "Hello!" let pairs = Array(zip(string, repeatElement(1, count: string.count))) let counts = Dictionary(pairs, uniquingKeysWith: +) // ["H": 1, "e": 1, "o": 1, "l": 2, "!": 1]
Exemplul 3:
Folosind metoda de merge
:
let values = ["a": 1, "b": 5] var additionalValues = ["b": 3, "c": 2, "a": 3] additionalValues.merge(values, uniquingKeysWith: +) // ["b": 8, "c": 2, "a": 4]
Indice cu valoare implicită
Anterior, o practică obișnuită era aceea de a utiliza operatorul de coalescență zero pentru a da o valoare implicită în cazul în care valoarea este zero.
Swift 3:
let dict = ["a": 1, "b": 5] dict["c"] ?? 0 // 0
Swift 4 introduce o nouă valoare default
pe indici (parte din SE-0165):
let dict = ["a": 1, "b": 5] dict["c", default: 0] // 0, equals to `dict["c"] ?? 0` in Swift 3
De asemenea, puteți muta un dicționar în timp ce îl subscrieți cu valoarea implicită:
let string = """ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam mattis lorem et leo laoreet fermentum. Mauris pretium enim ac mi tempor viverra et fermentum nisl. Sed diam nibh, posuere non lectus at, ornare bibendum erat. Fusce mattis sem ac feugiat vulputate. Morbi at nunc maximus, vestibulum orci et, dictum neque. Vestibulum vulputate augue ac libero vulputate vestibulum. Nullam blandit et sapien non fermentum. Proin mollis nisl at vulputate euismod. """ var wordsCountByLine = [Int: Int]() let lines = string.split(separator: "\n") for (index, line) in lines.enumerated() { let lineWordsCount = line.split(separator: " ").count wordsCountByLine[index, default: 0] += lineWordsCount } print(wordsCountByLine) // [2: 10, 4: 15, 5: 7, 6: 6, 7: 6, 0: 8, 1: 7, 3: 10]
Hartă și filtru specifice dicționarului
Gruparea elementelor secvenței
Tipuri asociate constrânse în protocoale
Propunerea SE-0142 introduce adăugarea de clauze condiționale la declarațiile de tip asociate.
extension Sequence where Element: Numeric { var sum: Element { var result: Element = 0 for element in self { result += element } return result } } [1,2,3,4].sum
Arhivare și serializare (codificare / decodare)
Anterior, pentru a serializa un anumit tip personalizat, ar trebui să utilizați protocolul NSCoding
vechi și bine cunoscut. Problema este că tipurile care nu sunt de clasă, cum ar fi struct
și enum
nu pot conforma acestui protocol, așa că dezvoltatorii nu au avut nimic de făcut decât să utilizeze hacks, cum ar fi furnizarea unui strat suplimentar de compatibilitate, creând o clasă imbricată care ar putea fi conformă NSCoding
.
Swift 4 are o soluție foarte convenabilă la această problemă datorită SE-0166 - o introducere a protocolului Codable
:
struct Employee: Codable { let name: String let age: Int let role: Role enum Role: String, Codable { case manager case developer case admin } } struct Company { let name: String let officeLocation: Location? let employees: [Employee] } struct Location : Codable { let latitude: Double let longitude: Double }
Într-un caz simplu ca acesta, tot ce aveți nevoie este să adăugați conformitatea protocolului Codable
la toate tipurile dvs. personalizate, compilatorul va face toată magia pentru dvs. Asta e!
Codable
este un typealias
pentru o compoziție a Decodable
& Encodable
protocoale, astfel încât să puteți declara, de exemplu, numai Decodable
conformitate protocol dacă doriți să decodeze tipul de exemplu de la date JSON.
Codificare
Dacă doriți să serializați sau deserializați o valoare Codable
- trebuie să utilizați un codificator sau un obiect decodor. Swift 4 vine deja cu un set de codificatoare / decodificatoare pentru JSON și liste de proprietăți, precum și noi CocoaError
pentru diferite tipuri de erori care ar putea fi aruncate în timpul codificării / decodificării. NSKeyedArchiver
și NSKeyedUnarchiver
acceptă, de asemenea, tipuri Codable
.
let employee = Employee(name: "Peter", age: 27, role: .manager) let company = Company(name: "Awesome Company", officeLocation: nil, employees: [employee]) let encoder = JSONEncoder() let companyData = try encoder.encode(company) let string = String(data: companyData, encoding: .utf8)! print(string) >>> { "name" : "Awesome Company", "employees" : [ { "name" : "Peter", "age" : 27, "role" : "manager" } ] }
O bucată de tort, nu-i așa?
Decodare
Decodorul este folosit pentru a deserializa tipul personalizat Codable
din Data
. Nu știe ce tip să decodeze din date în sine, deci ar trebui să specificați ce tip să decodificați, de exemplu, Employee
sau [Employee]
:
let decoder = JSONDecoder() let jsonData = """ [ { "name" : "Peter", "age" : 27, "role" : "manager" }, { "name" : "Alex", "age" : 26, "role" : "developer" }, { "name" : "Eugene", "age" : 30, "role" : "admin" } ] """.data(using: .utf8)! let employees = try decoder.decode([Employee].self, from: jsonData)
If one of `Codable` type instances fails to decode, then whole collection will fail to decode.
Nume cheie personalizate
În majoritatea cazurilor, numele pe care le folosim în tipurile Swift personalizate nu se potrivesc cu tastele din datele JSON care reprezintă acest tip. Pentru a crea o mapare între numele proprietăților de tip personalizat și cheile JSON puteți crea o enum imbricată numită CodingKeys
care ar trebui să respecte protocolul CodingKey
:
struct Country: Decodable { let id: String let name: String let phoneCode: String private enum CodingKeys: String, CodingKey { case id = "alpha3" case name case phoneCode = "phone_code" } }
Decodare personalizată
Dacă aveți un caz complex, puteți implementa inițializatorul personalizat dintr-un protocol Decodable
:
struct Transaction { let id: Int let action: String let source: String let amount: Int let state: TransactionState let createdAt: Date let authorName: String enum TransactionState: String, Decodable { case done case canceled case processed } } extension Transaction: Decodable { private enum CodingKeys: String, CodingKey { case id case action = "action_name" case source = "source_name" case amount case state case createdAt = "created_at" case author } private enum AuthorKeys: String, CodingKey { case fullName = "full_name" } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) id = try container.decode(Int.self, forKey: .id) actionName = try container.decode(String.self, forKey: .action) sourceName = try container.decode(String.self, forKey: .source) let createdAtValue = try container.decode(Double.self, forKey: .createdAt) createdAt = Date(timeIntervalSince1970: createdAtValue) state = try container.decode(TransactionState.self, forKey: .state) amount = try container.decodeIfPresent(Int.self, forKey: .amount) ?? 0 do { let authorContainer = try container.nestedContainer(keyedBy: AuthorKeys.self, forKey: .author) authorName = try authorContainer.decode(String.self, forKey: .fullName) } catch { authorName = "" } } }
Codare valoare cheie
Una dintre caracteristicile utile pe care le aduce Swift 4 sunt Smart KeyPaths descrise în SE-0161. Spre deosebire de Swift 3 #keyPath()
, care nu este puternic tastat și funcționează doar pentru membrii Objective-C, Swift 4 KeyPath este o clasă generică, ceea ce înseamnă că căile cheie sunt acum puternic tastate. Să ne aruncăm în câteva exemple:
struct User { var username: String }
Forma generală a căii cheii \<Type>.<path>
, unde <Type>
este un nume de tip și <path>
este un lanț cu una sau mai multe proprietăți, de exemplu, \User.username
:
let user = User(username: "max") let username = user[keyPath: \User.username] // "max"
De asemenea, puteți scrie o nouă valoare prin această cale cheie dacă este mutabilă:
var user = User(username: "max") user[keyPath: \User.username] = "alex" // "alex"
Căile cheie nu sunt limitate la un nivel de ierarhie:
struct Comment { let content: String var author: User } let max = User(username: "max") let comment = Comment(content: "Nice post!", author: max) let authorUsername = comment[keyPath: \Comment.author.username] // "max"
Căile cheie pot fi stocate într-o variabilă:
let authorKeyPath = \Comment.author let usernameKeyPath = authorKeyPath.appending(path: \.username) let authorUsername = comment[keyPath: usernameKeyPath] // "max"
De asemenea, puteți utiliza căi cheie pentru proprietăți opționale și calculate:
struct Post { let title: String var comments: [Comment] var topComment: Comment? { return comments.first } } let max = User(username: "max") let alex = User(username: "alex") var post = Post(title: "What's new in Swift 4", comments: []) let topCommentAuthorUsernameKeyPath = \Post.topComment?.author.username post[keyPath: topCommentAuthorUsernameKeyPath] // nil let comment = Comment(content: "", author: alex) let anotherComment = Comment(content: "Nice post!", author: max) post.comments = [comment, anotherComment] post[keyPath: topCommentAuthorUsernameKeyPath] // "alex"
În ciuda faptului că SE-0161 evidențiază indicii de suport în căile cheie, acestea nu au fost încă implementate:
post.comments[keyPath: \.[0].content] // error: key path support for subscript components is not implemented let firstCommentAuthorKeyPath = \Post.comments[0].author // error: key path support for subscript components is not implemented
KVO
În plus față de căile noi de chei, API-ul de observare a valorilor cheie a fost actualizat și în Swift 4.
New KVO APIs depend on Objective-C runtime and works for `NSObject` subclasses only, so it can't be used for Swift structs and classes which don't inherit `NSObject`. In order to observe property it should be marked as `@objc dynamic var`.
class User: NSObject { @objc dynamic var name: String var username: String init(name: String, username: String) { self.name = name self.userName = userName super.init() } } let user = User(name: "Max", username: "max") let nameObservation = user.observe(\.name, options: [.new, .old]) { user, change in // NSKeyValueObservation if let oldValue = change.oldValue, let newValue = change.newValue { print("fullName has changed from \(oldValue) to \(newValue)") } else { print("fullName is now \(user.name)") } } user.name = "Alex" // name has changed from Max to Alex
Apelați metoda invalidate()
dacă doriți să opriți observarea
nameObservation.invalidate() user.name = "Elina" // observer isn't get called
De asemenea, este oprit când este dezinitiat, deci asigurați-vă că îl stocați în proprietate sau în altă parte dacă doriți să îl păstrați.
Intervaluri unilaterale
SE-0172 introduce intervale „unilaterale”, create prin versiuni de prefix / postfix ale operatorilor de intervale existente și un nou protocol RangeExpression
pentru a simplifica crearea metodelor care iau diferite tipuri de intervale.
Secvențe Infinite
Puteți utiliza un interval unilateral pentru a construi o secvență infinită:
let letters = ["a", "b", "c", "d"] let numberedLetters = Array(zip(1..., letters)) // [(1, "a"), (2, "b"), (3, "c"), (4, "d")]
let string = "Hello, Mind Studios!" let index = string.index(of: ",")! string[..<index] // "Hello" string[...index] // "Hello,"
Utilizarea intervalelor unilaterale în potrivirea modelelor
let value = 5 switch value { case 1...: print("greater than zero") case 0: print("zero") case ..<0: print("less than zero") default: break }
Indice generice
SE-0148 Subscripturile pot avea acum argumente generice și tipuri de returnare
struct JSON { let data: [String: Any] subscript<T>(key: String) -> T? { return data[key] as? T } } let jsonDictionary: [String: Any] = [ "name": "Ukraine", "flag": "", "population": 42_500_000 ] let json = JSON(data: jsonDictionary) let population: Int? = json["population"] // 42500600
extension Dictionary where Value == String { subscript<T: RawRepresentable>(key: Key) -> T? where T.RawValue == Value { guard let string = self[key] else { return nil } return T(rawValue: string) } } enum Color: String { case red case green case blue } let dictionary = [1: "red"] let color: Color? = dictionary[1] // red
Limitarea inferenței Objective-C
Swift 4 minimizează inferența @objc, limitându-l doar la acele cazuri în care declarația trebuie să fie disponibilă pentru Objective-C (SE-0160).
Aceasta scade dimensiunea binară a aplicației dvs. prin necompilarea codului redundant Objective-C dacă nu îl utilizați și oferă mai mult control asupra momentului când @objc va fi dedus. Clasele derivate din NSObject nu mai inferesc @objc.
Dar există unele situații în care codul Swift va continua să aibă o deducție implicită:
Declarații care au un atribut @objc
Declarații care îndeplinesc o cerință a unui protocol @objc
Declarații care au atribute @IBAction, @IBInspectable, @IBOutlet, @NSManaged, @GKInspectable
Pentru a activa inferența @objc pentru o întreagă clasă, puteți utiliza noul atribut @objcmembers.
Pentru a dezactiva inferența @objc pentru o anumită extensie sau funcție - adăugați noul atribut @nonobjc.
Compunerea de clase și protocoale
În Swift 4 putem compune acum protocoale împreună cu alte tipuri de Swift:
User & Codable & CustomStringConvertible typealias MyType = User & Codable & CustomStringConvertible
Beneficiile Swift 4.
Avantajele Swift 4 sunt cu adevărat imense, deoarece se întâmplă adesea când Apple lansează o nouă versiune lingvistică. În afară de performanțele lingvistice îmbunătățite, a stabilizat și procesul de migrare. Revenind la procesul de migrare Swift 2.2 la 3.0, ne reamintim procesul perplex al transferului tuturor dependențelor. Modificările Swift 4.0 ne permit să părăsim bibliotecile terților fără a le „muta” de fapt - trebuie doar să actualizați Swift în sine.
De asemenea, în ceea ce privește îmbunătățirile Swift 4.0 vs 3.0, dimensiunea fișierelor binare compilate a fost modificată, ceea ce a dus la scăderea dimensiunii aplicației; De exemplu, aplicația mobilă cântăreaște 20 MB, iar în cea mai nouă versiune Swift va dura aproximativ 17 MB. Și există o diferență de bază între Swift 4 și Swift 3 - remedierea erorilor s-a întâmplat, iar limbajul a devenit puțin mai rapid.
Au trecut ani de când Swift a fost utilizat și continuă să evolueze cu fiecare actualizare viitoare. Cu fiecare nou limbaj reînnoiți noi perspective de dezvoltare, necunoscute înainte, apar și așteptăm cu nerăbdare să explorăm noi orizonturi iOS.
Nu ratați articolul nostru despre MVP vs MVC vs MVVM vs VIPER pentru dezvoltarea iOS.
Scris de Max Mashkov și Elina Bessarabova .