티스토리 뷰
출처
Api Changes
String
var str = "Hello🐮"
for char in str {
print(char)
}
direct 로 돌 수 있듯이,
Sequence, Collection 의 기능들을 모두 사용할 수 있습니다.
let count = str.count
let isEmpty = str.isEmpty
let elloString = str.dropFirst()
let lloString = str.dropFirst(2)
let reverseString = String(str.reversed())
let filterString = str.filter { (char) -> Bool in
let isAscii = char.unicodeScalars.reduce(true, { (result, scalar) -> Bool in
return result && scalar.isASCII
})
return isAscii
}
Swift 4 에서는 String 의 subsequence 로 Substring type 이 제공됩니다.
StringProtocol 이 추가되습니다.
String, SubString 은 String Protocol 을 따르고 다양한 기능을 제공합니다.
let endIndex = str.index(str.startIndex, offsetBy: 4)
var helloSubString = str[str.startIndex...endIndex]
helloSubString += "🐮"
let helloWithEmoji = String(helloSubString)
let hasPrefix = helloWithEmoji.hasPrefix("He")
let hasSuffix = helloWithEmoji.hasSuffix("🐮")
String 이 이모티콘을 해석하는 방식이 변경되었습니다.
유니코드 때문에 다양한 code 들이 생성되었었는데요,
skin-tone 이 들어간 경우 4글자, 아니면 2글자의 unicode 로 해석되던 것이
모두 1글자로 해석되도록 변경되었습니다.
"👩💻".count // Now: 1, Before: 2
"👍🏽".count // Now: 1, Before: 2
"👨❤️💋👨".count // Now: 1, Before, 4
Dictionary and Set
Sequence Based Initialization
sequence key-value pair 로 Dictionary 를 만들 수 있습니다.
let nearestStarNames = ["Proxima Centauri", "Alpha Centauri A", "Alpha Centauri B", "Barnard's Star", "Wolf 359"]
let nearestStarDistances = [4.24, 4.37, 4.37, 5.96, 7.78]
let starDistanceDict = Dictionary(uniqueKeysWithValues: zip(nearestStarNames, nearestStarDistances))
// ["Wolf 359": 7.78, "Alpha Centauri B": 4.37, "Proxima Centauri": 4.24,
//"Alpha Centauri A": 4.37, "Barnard's Star": 5.96]
Duplicate Key Resolution
Array 에 duplicate 정보가 들어있을 때도 쉽게 key 값으로 변경하여 사용할 수 있습니다.
let intElement = repeatElement(1, count: favoriteStarVotes.count) //1, 1, 1, 1
let keysAndValues = zip(favoriteStarVotes, intElement)
let mergedKeysAndValues = Dictionary(keysAndValues, uniquingKeysWith: +)
// ["Barnard's Star": 1, "Alpha Centauri A": 2, "Wolf 359": 1]
Dictionary Mapping
Dictionary 의 mapValues 를 통해 value 들에 직접 접근에 수정할 수 있습니다.
let mappedCloseStars = closeStars.mapValues { "\($0)" }
mappedCloseStars // ["Proxima Centauri": "4.24", "Alpha Centauri A": "4.37", "Alpha Centauri B": "4.37"]
Dictionary Default Values
//Get
let siriusDistance = mappedCloseStars["Wolf 359", default: "unknown"] // "unknown"
//Set
var starWordsCount: [String: Int] = [:]
for starName in nearestStarNames {
let numWords = starName.split(separator: " ").count
starWordsCount[starName, default: 0] += numWords
// ["Wolf 359": 2, "Alpha Centauri B": 3, "Proxima Centauri": 2,
//"Alpha Centauri A": 3, "Barnard's Star": 2]
}
Dictionary Grouping
let starsByFirstLetter = Dictionary(grouping: nearestStarNames) { $0.first! }
// ["B": ["Barnard's Star"], "A": ["Alpha Centauri A", "Alpha Centauri B"],
//"W": ["Wolf 359"], "P": ["Proxima Centauri"]]
Reserving Capacity
Collection 에서 reallocation 은 큰 비용을 차지하는데요,
reserveCapacity(_:) 로 성능향상을 도모할 수 있습니다.
starWordsCount.capacity // 6
starWordsCount.reserveCapacity(20) // reserves at _least_ 20 elements of capacity
starWordsCount.capacity // 24
Private Access Modifier
struct SpaceCraft {
private let warpCode: String
init(warpCode: String) {
self.warpCode = warpCode
}
}
extension SpaceCraft {
func goToWarpSpeed(warpCode: String) {
if warpCode == self.warpCode {
// Error in Swift 3 unless warpCode is fileprivate
print("Do it Scotty!")
}
}
}
let enterprise = SpaceCraft(warpCode: "KirkIsCool")
enterprise.goToWarpSpeed(warpCode: "KirkIsCool") // "Do it Scotty!"
Api Additions
Archival and Serialization
struct CuriosityLog: Codable {
enum Discovery: String, Codable {
case rock, water, martian
}
var sol: Int
var discoveries: [Discovery]
}
// Create a log entry for Mars sol 42
let logSol42 = CuriosityLog(sol: 42, discoveries: [.rock, .rock, .rock, .rock])
Key-Value Coding
struct Lightsaber {
enum Color {
case blue, green, red
}
let color: Color
}
class ForceUser {
var name: String
var lightsaber: Lightsaber
var master: ForceUser?
init(name: String, lightsaber: Lightsaber, master: ForceUser? = nil) {
self.name = name
self.lightsaber = lightsaber
self.master = master
}
}
let sidious = ForceUser(name: "Darth Sidious", lightsaber: Lightsaber(color: .red))
let obiwan = ForceUser(name: "Obi-Wan Kenobi", lightsaber: Lightsaber(color: .blue))
let anakin = ForceUser(name: "Anakin Skywalker", lightsaber: Lightsaber(color: .blue), master: obiwan)
let nameKeyPath = \ForceUser.name
let obiwanName = obiwan[keyPath: nameKeyPath] // "Obi-Wan Kenobi"
let anakinSaberColor = anakin[keyPath: \ForceUser.lightsaber.color] // blue
let masterKeyPath = \ForceUser.master
let anakinMasterName = anakin[keyPath: masterKeyPath]?.name // "Obi-Wan Kenobi"
anakin[keyPath: masterKeyPath] = sidious
anakin.master?.name // Darth Sidious
Multi-line String Literals
let star = "⭐️"
let introString = """
A long time ago in a galaxy far,
far away....
You can even dynamically add values
from properties: \(star)
"""
One-Sided Ranges
var planets = ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"]
let outsideAsteroidBelt = planets[4...] // Before: planets[4..<planets.endIndex]
let firstThree = planets[..<4] // Before: planets[planets.startIndex..<4]
Infinite Sequence
var numberedPlanets = Array(zip(1..., planets))
print(numberedPlanets) // [(1, "Mercury"), (2, "Venus"), ..., (8, "Neptune")]
planets.append("Pluto")
numberedPlanets = Array(zip(1..., planets))
print(numberedPlanets) // [(1, "Mercury"), (2, "Venus"), ..., (9, "Pluto")]
Pattern matching
func temperature(planetNumber: Int) {
switch planetNumber {
case ...2: // anything less than or equal to 2
print("Too hot")
case 4...: // anything greater than or equal to 4
print("Too cold")
default:
print("Justtttt right")
}
}
temperature(planetNumber: 3) // Earth
Generic Subscripts
struct GenericDictionary<Key: Hashable, Value> {
private var data: [Key: Value]
init(data: [Key: Value]) {
self.data = data
}
subscript<T>(key: Key) -> T? {
return data[key] as? T
}
}
var earthData = GenericDictionary(data: ["name": "Earth",
"population": 7500000000,
"moons": 1])
let name: String? = earthData["name"]
let population: Int? = earthData["population"]
extension GenericDictionary {
subscript<Keys: Sequence>(keys: Keys) -> [Value] where Keys.Iterator.Element == Key {
var values: [Value] = []
for key in keys {
if let value = data[key] {
values.append(value)
}
}
return values
}
}
let nameAndMoons = earthData[["moons", "name"]] // [1, "Earth"]
let nameAndMoons2 = earthData[Set(["moons", "name"])] // [1, "Earth"]
Miscellaneous
MutableCollection.swapAt(_:_:)
func bubbleSort<T: Comparable>(_ array: [T]) -> [T] {
var sortedArray = array
for i in 0..<sortedArray.count - 1 {
for j in 1..<sortedArray.count {
if sortedArray[j-1] > sortedArray[j] {
sortedArray.swapAt(j-1, j) // New MutableCollection method
}
}
}
return sortedArray
}
bubbleSort([4, 3, 2, 1, 0]) // [0, 1, 2, 3, 4]
Associated Type Constraints
protocol MyProtocol {
associatedtype Element
associatedtype SubSequence : Sequence where SubSequence.Iterator.Element == Iterator.Element
}
Class and Protocol Existential
protocol MyProtocol { }
class View { }
class ViewSubclass: View, MyProtocol { }
class MyClass {
var delegate: (View & MyProtocol)?
}
let myClass = MyClass()
myClass.delegate = ViewSubclass()
NSNumber Bridging
let n = NSNumber(value: 999)
let v = n as? UInt8 // Swift 4: nil, Swift 3: 231
'iOS 개발 > Swift' 카테고리의 다른 글
[Swift 4] Swift 3 -> Swift 4 Migration (Limiting @objc inference) (0) | 2017.09.21 |
---|---|
[Swift 3] DispatchSemaphore 사용하기 (0) | 2017.06.11 |
[Swift 3] DispatchGroup 사용하기 (0) | 2017.06.09 |
[Swift] Objective C 프로젝트에서 Swift 를, Swift 프로젝트에서 Objective C 를 사용하기 (1) | 2017.06.08 |
[Swift 3.0] Dispatch Queue 사용하기 (0) | 2017.06.06 |
- Total
- Today
- Yesterday
- Block
- AWS
- optional
- applicationWillResignActive
- delegate
- Swift3
- NSManagedObjectModel
- NSManagedObject
- dictionary
- coredata
- Swift
- ios
- 꺼내먹어요
- Arc
- set
- NSManagedObjectContext
- HTTP
- RunLoop
- CGImage
- UIView
- string
- 읽기 좋은 코드가 좋은 코드다
- Swfit
- EffectiveObjectiveC
- Swift 3
- Swift 3.0
- thread
- workerThread
- docker
- CIImage
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |