Swift 4.0 vs Swift 3.0 - Farklılıklar ve Yeni Özellikler
Yayınlanan: 2021-10-05Apple'ın iyi bilinen Swift dilinin yeni bir sürümünü yayınladığı gün nihayet bizi vurdu. Ondan ne beklemeliyiz? Beklentiler titrerken, Swift 4 sürümünde yer alacak yeni güncellemelere dair küçük bir genel bakış sunmaya karar verdik.
3 Swift'in temel taşları.
Kod yazmak için harika bir dil olan Swift'in kendi avantajları vardır ve Objective-C dilinden "daha uzun yaşadığı" iddia edilmektedir.
Swift ve Objective-C arasındaki temel farkları okuyabilirsiniz.
Swift hızlıdır , yazı tipi açısından güvenlidir ve çok etkileyicidir . Telefonlarda ve tabletlerde, masaüstlerinde ve sunucularda yazılım yazmak için kullanılabilir - görünüşe göre kod çalıştıran her şeyde. Apple'ın kod yazmayı öğrenen Swift Playgrounds uygulamasıyla veya Xcode'daki Playgrounds'ı kullanarak, çalışmanızın sonuçlarını hemen görebilirsiniz, bir uygulamayı geliştirmeye ve çalıştırmaya burnunuzu sokmanıza gerek yok. ilk yer. Her yeni eklenti sürümü ile daha iyi ve daha hızlı hale gelir ve Swift 4 sürümünde durum böyledir.
Sürekli hazır?
Xcode 9'un Swift 4 için sahip olduğu bir başka harika özellik - yaklaşan geçiş hakkında fazla endişelenmenize gerek yok ve bu makaleyi okurken nedenini anlayacaksınız.
Bunlardan bahsetmişken, bu sonbaharın bize getirdiği bonbon ve Swift 4 yeni özelliklerini kısaca inceleyelim.
Başlarken
Geliştiriciler dünyasında Xcode olan kullanışlı bir IDE olmadan dilin kendisi pek kullanışlı değildir. Xcode 9'un en son sürümünü Mac App Store'dan veya Apple Developer sitesindeki İndirilenler sayfasından indirebilirsiniz, ancak öncelikle aktif bir geliştirici hesabınız olduğundan emin olun. Oldukça kararlıdır, böylece günlük kodlama rutinleriniz için Xcode 8'i onunla değiştirebilirsiniz.
Ayrıca xcversion kullanarak birden çok Xcode sürümünü de yükleyebilirsiniz.
Yeni bir projeye başlıyorsanız - gitmeye hazırsınız. Ancak zaten Swift 3.x ile yazılmış bir projeniz varsa - bir geçiş sürecinden geçmeniz gerekir.
Yeni özellikleri kullanmaya alışmak için öncelikle Playground'da denemenizi öneririz.
Bu makaleyi okurken Swift Evolution tekliflerine 'SE-____' formatında bağlantılar göreceksiniz.
Swift 4'e Geçiş
Swift'in bir ana sürümünden diğerine geçiş, özellikle Swift 2.x'ten 3.0'a her zaman oldukça yoğun olmuştur. Genellikle proje başına 1-2 gün sürer, ancak Swift 4'e geçiş biraz daha kolaydır ve çok daha hızlı geçilebilir.
Göç öncesi hazırlık
Xcode 9, yalnızca Swift 4'ü değil, aynı zamanda bir geçiş sürümü 3.2'yi de destekler, bu nedenle projeniz zorlu zorluklar olmadan derlenmelidir. Bu mümkündür çünkü Swift 4 derleyicisi ve geçiş aracı dilin her iki sürümünü de destekler. Hedef başına farklı Swift sürümleri belirleyebilirsiniz; bu, bazı üçüncü taraf kitaplıkları henüz güncellenmediyse veya projenizde birden fazla hedefiniz varsa çok yararlıdır. Ancak, yalnızca dil değil, SDK'da da bazı değişiklikler var, bu nedenle Apple SDK API'lerini düzenlemeye devam ederken büyük olasılıkla kodunuza bazı güncellemelerin uygulanması gerekecek...
Hızlı geçiş aracı
Her zaman olduğu gibi Apple, önceki Swift sürümünden geçişe yardımcı olabilecek Xcode içinde paketlenmiş Swift geçiş aracı sağlar. Düzenle -> Dönüştür -> Geçerli Swift Sözdizimine… seçeneğine giderek ve dönüştürmek istediğiniz hedefleri seçerek Xcode'da başlatabilirsiniz.
Ardından, hangi Objective-C çıkarım tercihini uygulamak istediğiniz sorulacak:
Swift 4'te ek değişiklikler baskın olduğundan, Swift geçiş aracı değişikliklerin çoğunu sizin için yönetecek.
CocoaPod'lar
Çoğu geliştiricisi projeleri için CocoaPods bağımlılık yöneticisini kullanır çünkü Swift Paket Yöneticisi çok hızlı gelişmesine rağmen olabileceği kadar olgun değildir. Yukarıda belirtildiği gibi, üçüncü taraf kitaplıkların tümü henüz Swift 4'e güncellenmedi, bu nedenle bazılarını derlerken hatalar görebilirsiniz. Bu sorunu çözmek için olası bir çözüm, size Podfile
bir post_install
betiği ekleyerek henüz güncellenmemiş olan bölmeler için Swift sürüm 3.2
belirtmektir:
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
O zaman koş
pod install
Artık bölmeleri hatasız derleyebilirsiniz.
Şimdi Swift 4 API değişiklik ve eklemelerini inceleyelim.
API değişiklikleri ve eklemeleri
Teller
SE-0163 önerisi sayesinde String
artık Collection
protokolüne uygundur. Swift 1.x'i hatırlıyor musunuz?
Doğrudan String
üzerinde yineleyebileceğiniz için artık characters
dizisi özelliğine gerek yoktur:
let string = "Hello, Mind Studios!" for character in string { print(character) }
Bu aynı zamanda String
üzerinde count
, isEmpty
, map()
, filter()
, index(of:)
ve çok daha fazlası gibi herhangi bir Collection
yöntemini ve özelliğini kullanabileceğiniz anlamına gelir:
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"
Yeni Substring
türü
Swift 4, String
bir alt dizisini temsil eden yeni Substring
tipini getiriyor (yukarıda bahsedilen SE-0163'te açıklandığı gibi).
// Split string into substrings let string = "Hello, Mind Studios!" let parts = string.split(separator: " ") // ["Hello,", "Mind", "Studios!"] type(of: parts.first!) // Substring.Type
Hem String
hem de Substring
artık onları neredeyse aynı ve birlikte çalışabilir hale getiren yeni StringProtocol
destekliyor:
var hello = parts.first! // Concatenate a String onto a Substring hello += " !" // "Hello, !" // Create a String from a Substring let helloDog = String(hello) // "Hello, !"
Önemli Not
SE-0163'ün çok önemli bir notu var:
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.
Bu, Substring
, String
dizisi için geçici bir depolama olarak kullanılması amaçlandığı anlamına gelir. Bazı yöntemlere veya diğer sınıflara iletmek istiyorsanız - önce onu String
dönüştürün:
let substring: Substring = ... // Substring let string = String(substring) // String someMethod(string)
Her neyse, Swift'in tür sistemi, String
beklendiği bir yerde Substring
yardımcı olacaktır (parametre türü olarak new StringProtocol
kullanmadığınızı varsayarak).
Çok satırlı dize değişmezleri
SE-0168, üç çift tırnak """
kullanan çok satırlı dize değişmezleri için basit bir sözdizimi sunar; bu, çoğu metin biçiminin (JSON veya HTML gibi) veya bazı uzun metinlerin herhangi bir kaçış olmadan yapıştırılabileceği anlamına gelir:
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. """
Dize değişmezlerinde kaçan yeni satırlar
SE-0182, satırın sonunda ters eğik çizgi ile çok satırlı dize değişmezlerinde yeni satırlardan kaçma yeteneği ekler.
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
Geliştirilmiş Unicode desteği
Swift 4, Unicode 9 için destek getiriyor; bu, artık unicode karakter sayma sorunlarının ortadan kalktığı anlamına geliyor:
"".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
Yukarıda vurgulanan tüm değişiklikler ve uygulanan öneriler (diğerleri gibi), köklerini String Manifesto adı verilen geniş bir şekilde tanımlanmış bir dizi özellikten almaktadır.
Giriş kontrolu
Swift 3, Erişim kontrolüne çok çelişkili bir öğe getirdi - gerçekten kafa karıştırıcı olabilen fileprivate
erişim değiştiricisi.
Önceden, tür üyelerini diğer türlerden gizlemek için private
erişim düzeyi değiştiricisi kullanılıyordu ve özel üyelere yalnızca tür tanımında tanımlanan yöntemler ve özelliklerle erişilebiliyordu, bu üyelere erişemedikleri için aynı tür uzantıları bir kenara bırakılmıştı.
fileprivate
, aynı dosya içindeki özellikler ve yöntemler gibi tür üyelerine erişimi paylaşmak için kullanılabilir.
Aslında private
kullanımı, bazı fileprivate
bu tür üyelere erişimi olmadığında bir soruna yol açtı, bu nedenle bu tür durumlarda fileprivate
kullanmak çok yaygın bir çözümdü ve bu da başka bir soruna yol açtı: diğer türler aynı dosya bu üyelere de erişebilir.
Swift 4, türdeki uzantıların SE-0169'da açıklandığı gibi aynı dosyada o türün private
üyelerine erişmesine izin vererek işleri düzene sokar:
struct User { private let firstName: String private let lastName: String } extension User: CustomStringConvertible { var description: String { return "User: \(firstName) \(lastName)" } }
Sözlük ve Küme
Sequence
Dictionary
Başlatma
Dictionary
şimdi Sequence
ile başlatılabilir, ancak bu başlatıcıda tüm diziler iletilemez, yalnızca tuples (Key, Value)
içeren diziler iletilebilir; burada Key
, Sözlük'ün anahtar türüdür ve Value
, Sözlük değer türünü temsil eder:
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]
Burada zip
işlevi 2 diziden bir çift oluşturur ( Tuple
s), bu işlev hakkında daha fazla bilgiyi Swift Standard Library belgelerinde okuyabilirsiniz.
Sözlükleri Birleştirme
Bir Tuple
dizisinden bir sözlük oluştururken, 2 özdeş anahtarın değerlerini birleştirmek için kullanılan uniquingKeysWith
parametresine bir kapatma ileterek yinelenen anahtarların nasıl işleneceğini belirleyebilirsiniz.
Örnek 1:
let duplicates = [("a", 1), ("b", 5), ("a", 3), ("b", 3)] let dictionary = Dictionary(duplicates, uniquingKeysWith: { (first, _) in return first }) // ["b": 5, "a": 1]
Burada aynı anahtarla sonraki tüm değerleri yok sayarak ilk değeri bırakıyoruz.
Örnek 2:
Dizede her karakterin kaç kez göründüğünü sayma.
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]
Örnek 3:
merge
yöntemini kullanarak:
let values = ["a": 1, "b": 5] var additionalValues = ["b": 3, "c": 2, "a": 3] additionalValues.merge(values, uniquingKeysWith: +) // ["b": 8, "c": 2, "a": 4]
Varsayılan değere sahip alt simge
Önceden, değerin sıfır olması durumunda varsayılan bir değer vermek için sıfır birleştirme operatörünü kullanmak yaygın bir uygulamaydı.
Hızlı 3:
let dict = ["a": 1, "b": 5] dict["c"] ?? 0 // 0
Swift 4, aboneliklerde yeni default
değer sunar (SE-0165'in bir parçası):
let dict = ["a": 1, "b": 5] dict["c", default: 0] // 0, equals to `dict["c"] ?? 0` in Swift 3
Varsayılan değerle abone olurken bir sözlüğü de değiştirebilirsiniz:
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]
Sözlüğe özel harita ve filtre
Sıra öğelerini gruplandırma
Protokollerde Kısıtlı İlişkili Tipler
Öneri SE-0142, ilişkili tür bildirimlerine koşullu tümcelerin eklenmesini sağlar.
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
Arşivleme ve Serileştirme (Kodlama / Kod Çözme)
Önceden, bazı özel türleri seri hale getirmek için eski ve iyi bilinen NSCoding
protokolünü kullanmanız NSCoding
. Sorun şu ki, struct
ve enum
gibi sınıf dışı türler bu protokole NSCoding
, bu nedenle geliştiricilerin, NSCoding
uyumlu olabilecek iç içe bir sınıf oluşturarak ek uyumluluk katmanı sağlamak gibi NSCoding
kullanmaktan başka yapacakları bir şey NSCoding
.
Swift 4, Codable
protokolün tanıtımı olan SE-0166 sayesinde bu soruna çok uygun bir çözüme sahiptir:
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 }
Bunun gibi basit bir durumda ihtiyacınız olan tek şey, tüm özel türlerinize Codable
protokol uyumluluğu eklemektir, derleyici sizin için tüm sihri yapacaktır. Bu kadar!
Codable
bir olan typealias
bir kompozisyon için Decodable
& Encodable
sen, örneğin, sadece beyan böylece, protokoller Decodable
JSON verilerinden senin tipin örneğini deşifre etmek isterseniz protokol uygunluk.
kodlama
Bir Codable
değeri seri hale getirmek veya seri Codable
istiyorsanız - ve kodlayıcı veya kod çözücü nesnesini kullanmanız gerekir. Swift 4, JSON ve özellik listeleri için bir dizi kodlayıcı/kod CocoaError
yanı sıra kodlama/kod çözme sırasında atılabilecek farklı hata türleri için yeni CocoaError
s ile birlikte gelir. NSKeyedArchiver
ve NSKeyedUnarchiver
ayrıca Codable
türleri de destekler.
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" } ] }
Bir parça kek, değil mi?
kod çözme
Dekoder serisi kaldırılmaya özel için kullanılan Codable
gelen tip Data
. Verilerden hangi türün kodunun çözüleceğini bilmiyor, bu nedenle hangi türün kodunun çözüleceğini belirtmelisiniz, örneğin, Employee
veya [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.
Özel Anahtar Adları
Çoğu durumda, özel Swift türlerinde kullandığımız adlar, bu türü temsil eden JSON verilerindeki anahtarlarla eşleşmez. Bir yuvalanmış enum adlı oluşturabileceğiniz özel tip özellikleri isimleri ve JSON tuşları arasında bir eşleme oluşturmak için CodingKeys
uygun olmalıdır CodingKey
protokolü:
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" } }
Özel Kod Çözme
Karmaşık bir durumunuz varsa, özel başlatıcınızı bir Decodable
protokolden 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 = "" } } }
Anahtar Değer Kodlaması
Swift 4'ün getirdiği kullanışlı özelliklerden biri SE-0161'de açıklanan Smart KeyPath'lerdir. #keyPath()
ve yalnızca Objective-C üyeleri için çalışan Swift 3 #keyPath()
farklı olarak, Swift 4 #keyPath()
genel bir sınıftır; bu, anahtar yollarının artık güçlü bir şekilde yazıldığı anlamına gelir. Bazı örneklere geçelim:
struct User { var username: String }
Anahtar yolunun genel biçimi \<Type>.<path>
, burada <Type>
bir tür adıdır ve <path>
bir veya daha fazla özelliğin zinciridir, örneğin, \User.username
:
let user = User(username: "max") let username = user[keyPath: \User.username] // "max"
Değişken ise, bu anahtar yolu ile yeni bir değer de yazabilirsiniz:
var user = User(username: "max") user[keyPath: \User.username] = "alex" // "alex"
Anahtar yollar tek bir hiyerarşi düzeyiyle sınırlı değildir:
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"
Anahtar yolları bir değişkende saklanabilir:
let authorKeyPath = \Comment.author let usernameKeyPath = authorKeyPath.appending(path: \.username) let authorUsername = comment[keyPath: usernameKeyPath] // "max"
İsteğe bağlı ve hesaplanmış özellikler için anahtar yolları da kullanabilirsiniz:
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"
SE-0161'in kilit yollardaki destek aboneliklerini vurgulamasına rağmen, bunlar henüz uygulanmadı:
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
Yeni anahtar yollarına ek olarak, anahtar/değer gözlemleme API'si de Swift 4'te güncellendi.
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
Gözlemi durdurmak istiyorsanız invalidate()
yöntemini çağırın.
nameObservation.invalidate() user.name = "Elina" // observer isn't get called
Tanımlandığında da durdurulur, bu yüzden onu korumak istiyorsanız mülkte veya başka bir yerde sakladığınızdan emin olun.
Tek Taraflı Aralıklar
SE-0172, mevcut aralık operatörlerinin önek/sonek sürümleri aracılığıyla oluşturulan "tek taraflı" aralıkları ve farklı türde aralıklar alan yöntemlerin oluşturulmasını basitleştirmek için yeni bir RangeExpression
protokolünü sunar.
Sonsuz Diziler
Sonsuz bir dizi oluşturmak için tek taraflı bir aralık kullanabilirsiniz:
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,"
Desen Eşleştirmede Tek Taraflı Aralıkları Kullanma
let value = 5 switch value { case 1...: print("greater than zero") case 0: print("zero") case ..<0: print("less than zero") default: break }
Genel Abonelikler
SE-0148 Abonelikler artık genel argümanlara ve dönüş türlerine sahip olabilir
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
Objective-C Çıkarımını Sınırlama
Swift 4, @objc çıkarımını yalnızca bildirimin Objective-C (SE-0160) için mevcut olması gereken durumlarla sınırlayarak en aza indirir.
Bu, kullanmazsanız gereksiz Objective-C kodunu derlemeyerek uygulamanızın ikili boyutunu azaltır ve @objc'nin ne zaman çıkarılacağı konusunda daha fazla kontrol sağlar. NSObject türetilmiş sınıflar artık @objc sonucunu çıkarmıyor.
Ancak Swift kodunun örtük bir çıkarım yapmaya devam edeceği bazı durumlar vardır:
@objc özniteliğine sahip bildirimler
@objc protokolünün bir gereksinimini karşılayan bildirimler
@IBAction, @IBInspectable, @IBOutlet, @NSManaged, @GKInspectable özniteliklerine sahip bildirimler
Tüm bir sınıf için @objc çıkarımını etkinleştirmek için yeni @objcmembers niteliğini kullanabilirsiniz.
Belirli bir uzantı veya işlev için @objc çıkarımını devre dışı bırakmak için yeni @nonobjc özniteliğini ekleyin.
Sınıfları ve Protokolleri Oluşturma
Swift 4'te artık diğer Swift türleriyle birlikte protokoller oluşturabiliyoruz:
User & Codable & CustomStringConvertible typealias MyType = User & Codable & CustomStringConvertible
Swift'in Faydaları 4.
Swift 4'ün avantajları gerçekten çok büyük, çünkü Apple yeni bir dil sürümü yayınladığında sıklıkla oluyor. Geliştirilmiş dil performansının yanı sıra, geçiş sürecini de büyük ölçüde stabilize etti. Aklımızı Swift 2.2'den 3.0'a geçiş sürecine geri çevirerek, tüm bağımlılıkları aktarmanın karmaşık sürecini hatırlıyoruz. Swift 4.0 değişiklikleri, üçüncü taraf kitaplıklarını gerçekten "yer değiştirmeden" bırakmamıza izin veriyor - sadece Swift'in kendisini güncellemeniz gerekiyor.
Ayrıca Swift 4.0 vs 3.0 geliştirmeleri ile ilgili olarak, derlenmiş ikili dosyaların boyutu değiştirildi, bu da uygulamanın boyutunun azalmasına neden oldu; örneğin mobil uygulama 20 MB ağırlığındaydı ve en yeni Swift versiyonunda yaklaşık 17 MB alacak. Ve Swift 4 ve Swift 3 arasında temel bir fark var - hata düzeltme gerçekleşti ve dil biraz daha hızlı hale geldi.
Swift'in kullanılmaya başlamasından bu yana yıllar geçti ve gelen her güncelleme ile gelişmeye devam ediyor. Her yeni dil yenilenmesiyle, daha önce bilinmeyen yeni geliştirme perspektifleri ortaya çıkıyor ve yeni iOS ufuklarını keşfetmeyi dört gözle bekliyoruz.
iOS geliştirme için MVP vs MVC vs MVVM vs VIPER hakkındaki makalemizi kaçırmayın.
Max Mashkov ve Elina Bessarabova tarafından yazıldı .