[iOS] iOS 스터디

iOS 스터디

for문

  1. 일반적인 사용법
let arr = [1,2,3,4,5,6,7,8,9,10]

for i in arr {
    if i % 2 == 0 {
        print(i)
    }
}
  1. where 문을 사용했을 때
for i in arr where i % 2 == 0 {
    print(i)
}
  1. forEach
arr.forEach {
    print($0)
}
  1. enumerate
let dict = [
    [1: "apple"],
    [2: "banana"],
    [3: "grape"],
    [4: "watermelon"],
]

for (key, value) in dict.enumerated() {
    print("key: \(key)")
    print("value: \(value)")
}

조건문

  1. 스위프트에서는 조건문의 괄호를 제거해도 된다(권장)
// 1번
if (flag) {
    print("true")
}
// 2번
if flag {
    print("true")
}

// 3번
if (flag && (num1 == num2)) {
    print("true")
}
// 4번
if flag && (num1 == num2) {
    print("true")
}
  1. ,(콤마)로 조건문 표현
// 1번
if flag1 && flag2 {...}

// 2번
if flag1, flag2 {...}

switch문

  1. 조건문과 똑같이 괄호 생략 가능
// 1번
switch (value) {
case pattern:
    code
default:
    code
}

// 2번
switch value {
case pattern:
    code
default:
    code
}
  1. break를 안적어도 된다
switch grade {
case "A":
    print("A")
    break
case "B":
    print("B")
    break
case "C":
    print("C")
    break
default: 
    print("D")
    break
}

switch grade {
case "A":
    print("A")
case "B":
    print("B")
case "C":
    print("C")
default: 
    print("D")
}
  1. case에 여러 패턴을 명시할 수 있다
switch grade {
case "A", "B":
    print("A, B")
case "C", "D", "E", "F":
    print("C, D, E, F")
default:
    break
}
  1. if 문과 비교
if grade == "A" {
    print("A")
} else if grade == "B" {
    print("B")
} else if grade == "C" {
    print("C")
} else {
    print("D")
}
    
switch grade {
case "A":
    print("A")
case "B":
    print("B")
case "C":
    print("C")

배열

// 1번
let arr1 = Array<String>()
// 2번
let arr2 = [String]()

guard let, if let

var value: Int?
value = 1

// 1번
func test1() {
    print("value: \(value!)")
    
    print("value: \(value ?? 0)")
}

// 2번 guard let
func test2() {
    guard let value = value else {
        print("value is empty")
        return
    }
    print(value)
}

// 3번 if let
func test3() {
    if let value = value {
        print(value)
    } else {
        print("value is empty")
    }
}

_의 의미

  1. 값을 받아서 사용하지 않을 때 사용
guard let _ = value else {
    return
}

let _ = sumNum(1,2)
  1. 함수 호출시 파라미터의 이름을 생략할 때 사용
// 1번
func underbarTest(name: String, age: Int) {
    print("name: \(name), age: \(age)")
}
underbarTest(name: "Example", age: 10)

// 2번
func underbarTest(_ name: String, _ age: Int) {
    print("name: \(name), age: \(age)")
}
underbarTest("Example", 10)

함수

  1. 여러개의 값을 리턴할 수 있다.
func printAvg(num1: Int, num2: Int, num3: Int) -> (total: Int, avg: Int) {
    let total = num1 + num2 + num3
    let avg = total/3
    return (total, avg)
}
  1. 여러개의 인자를 받을 수 있다.
func arithmeticMean(_ numbers: Double...) -> Double {
    var total: Double = 0
    for number in numbers {
        total += number
    }
    return total / Double(numbers.count)
}
  1. 읽는 방법
    • 함수타입은 일반적으로 right-associative
    • Int -> Int -> Int == Int -> (Int -> Int)
func stock(_ money: Int) -> Int {
    return money - 1
}

func bitcoin(_ money: Int) -> Int {
    return money - 2
}

func investment(highRisk: Bool) -> (Int) -> Int {
    return highRisk ? bitcoin : stock
}

let myChoice = investment(highRisk: true)
let currentMoney = 3
print(myChoice(currentMoney))

프로퍼티 get, set, didSet, willSet

1. 기본적인 사용법

public var someValue: Int {
    get {
        return someValue
    }
    set(newValue) {
        someValue = newValue
    }
}

스크린샷 2021-05-08 오후 6 09 14

2. 올바른 사용법

private var realValue: Int = 0
public var tempValue: Int {
    get {
        return realValue
    }
    set(newValue) {
        realValue = newValue
    }
}

3. 응용

private var realValue: Int = 0
public var tempValue: Int {
    get {
        return realValue
    }
    set(newValue) {
        if newValue < 1 {
            print("값은 1보다 작을 수 없습니다.")
        } else {
            realValue = newValue
        }
    }
}

4. didSet, willSet

var someValue: Int = 10 {
   didSet(oldVal) {
      //someValue의 값이 변경된 직후에 호출, oldVal은 변경 전 someValue의 값
   }
   willSet(newVal) {
      //someValue의 값이 변경되기 직전에 호출, newVal은 변경 될 새로운 값
   }
}

5. 응용

var score: Int = 0 {
   didSet {
      scoreLabel.text = "Score: \(score)"
   }

class func vs static func

  1. 두개 다 똑같이 객체를 생성하지 않고 호출할 수 있다.
class MyClass {
    static func test1() {
        print("static func")
    }
    
    class func test2() {
        print("class func")
    }
}

class SubClass {
    func printSomething() {
        MyClass.test1()
        MyClass.test2()
    }
}
  1. 상속에서의 차이

스크린샷 2021-05-08 오후 5 24 19


Performance of Map, Filter, Reduce vs for-in loop in Swift

1. for 문과 map의 성능 비교

// Map
let celsius = fahrenheit.map { (degreesFahrenheit) -> Double in
    return (degreesFahrenheit - 32.0) / 1.8
}

// For-in loop
var celsius = [Double]()
for degreesFahrenheit in fahrenheit {
    celsius.append((degreesFahrenheit - 32.0) / 1.8)
}

스크린샷 2021-05-08 오후 4 54 58

2. for 문과 filter의 성능 비교

// filter
let colds = fahrenheit.filter { (degreesFahrenheit) -> Bool in
    return degreesFahrenheit <= 68.0
}

// For-in loop
var colds = [Double]()     
for degreesFahrenheit in fahrenheit {
    if degreesFahrenheit <= 68.0 {
        colds.append(degreesFahrenheit)
    }
}

스크린샷 2021-05-08 오후 4 56 50

3. for 문과 reduce의 성능 비교

// reduce
let sum = fahrenheit.reduce(0.0) { (result, degreesFahrenheit) -> Double in
    return result + degreesFahrenheit
}


// For-in loop
var sum: Double = 0.0
        
for degreesFahrenheit in fahrenheit {
    sum += degreesFahrenheit
}

스크린샷 2021-05-08 오후 4 59 44

4. 함수 chaining (map + filter + reduce)의 성능

// map + filter + reduce
let sum = fahrenheit.map({ (degreesFahrenheit) -> Double in
    return (degreesFahrenheit - 32.0) / 1.8
}).filter({ (degreesCelsius) -> Bool in
    return degreesCelsius <= 20.0
}).reduce(0.0) { (result, degreesCelsius) -> Double in
    return result + degreesCelsius
}

// For-in loop
var sum: Double = 0.0
        
for degreesFahrenheit in fahrenheit {
    let degreesCelsius = (degreesFahrenheit - 32.0) / 1.8
    if degreesCelsius <= 20.0 {
        sum += degreesCelsius
    }
}

스크린샷 2021-05-08 오후 5 03 43

5. RxSwift에서의 함수 Chaining 성능

Observable.from(fahrenheit)
    .map({ (degreesFahrenheit) -> Double in
        return (degreesFahrenheit - 32.0) / 1.8
    })
    .filter({ (degreesCelsius) -> Bool in
        return degreesCelsius <= 20.0
    })
    .reduce(0.0, accumulator: ({ (result, degreesCelsius) -> Double in
        return result + degreesCelsius
    }))
    .subscribe(onNext: { sum in
        print(sum)
    })
    .disposed(by: disposeBag)

스크린샷 2021-05-08 오후 5 12 05


Closure

1. 기본적인 Closure

{ (매개변수 목록) -> 반환타입 in
    실행 코드
}

let sum: (Int, Int) -> Int = { (num1: Int, num2: Int) in
    return num1 + num2
}

let sumResult: Int = sum(1, 2)
print(sumResult)

2. Trailing Closures

func loadPicture(from server: Server, completion: (Picture) -> Void, onFailure: () -> Void) {
    if let picture = download("photo.jpg", from: server) { 
        completion(picture)
    } else {
        onFailure() 
    }
}

loadPicture(from: someServer) { picture in 
    someView.currentPicture = picture
} onFailure: {
    print("Couldn't download the next picture.") ß
}
func someClosure(completion: () -> Void) {
    print("someClosure")
}

someClosure {
    // do somethins
}

3. Escaping Closures


UserDefault