๐Ÿ“ฑ App Development Study/iOS๐ŸŽ

[Udemy iOS & Swift Bootcamp] Advanced Swift (Swift Structures, Internal/External Parameters, Access Levels, Tuples)

ibelieveinme 2023. 7. 26. 15:58
728x90

๊ณ„์‚ฐ๊ธฐ ์•ฑ์„ ๋งŒ๋“ค๋ฉด์„œ Advanced Swift ๋ฅผ ๋ฐฐ์›Œ๋ณด์ž.


1. ๋จผ์ € ์•„๋ž˜ ๋งํฌ์—์„œ Skeleton Project ๋ฅผ ๋‹ค์šด๋ฐ›์•„์ฃผ์ž.

https://github.com/appbrewery/Calculator-Advanced-Swift-iOS13

 

GitHub - appbrewery/Calculator-Advanced-Swift-iOS13: Learn to Code While Building Apps - The Complete iOS Development Bootcamp

Learn to Code While Building Apps - The Complete iOS Development Bootcamp - GitHub - appbrewery/Calculator-Advanced-Swift-iOS13: Learn to Code While Building Apps - The Complete iOS Development Boo...

github.com

 

2. ์ž…๋ ฅํ•œ ๋ฒ„ํŠผ ์ˆซ์ž๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ๊ณ„์‚ฐ๊ธฐ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์ฃผ์ž.

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var displayLabel: UILabel!
    private var isFinishedTypingNumber: Bool = true
    
    @IBAction func calcButtonPressed(_ sender: UIButton) {
        
        //What should happen when a non-number button is pressed
        isFinishedTypingNumber = true
    }
    
    @IBAction func numButtonPressed(_ sender: UIButton) {
        
        //What should happen when a number is entered into the keypad
        if let numberValue = sender.currentTitle {
            
            if isFinishedTypingNumber {
                displayLabel.text = numberValue
                isFinishedTypingNumber = false
            }
            else{
                displayLabel.text! += numberValue
            }
        }
    }
}

numButtonPressed ํ•จ์ˆ˜์—์„œ sender ๋กœ ๋ˆ„๋ฅธ ๋ฒ„ํŠผ์˜ text ๋“ค์„ ๊ฐ€์ ธ์˜จ๋‹ค.

๋งจ์ฒ˜์Œ 0์ผ ๋•Œ, 0์ด ์•ˆ์—†์–ด์ง€๋Š” ์˜ค๋ฅ˜๋ฅผ ๋ง‰๊ธฐ ์œ„ํ•ด isFinishedTypingNumber ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ–ˆ๋‹ค.

 

3. ์—ฐ์‚ฐ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์ฃผ์ž.

1) ๋จผ์ € ์ˆซ์ž์˜ ๋ถ€ํ˜ธ๋ฅผ ๋ฐ”๊ฟ”์ฃผ๋Š” +/- ๋ฒ„ํŠผ์„ ๊ตฌํ˜„ํ•ด๋ณด์ž.

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var displayLabel: UILabel!
    private var isFinishedTypingNumber: Bool = true
    
    
    @IBAction func calcButtonPressed(_ sender: UIButton) {
        //What should happen when a non-number button is pressed
        isFinishedTypingNumber = true
        
        guard let number = Double(displayLabel.text!) else {
            fatalError("cannot convert display label text to a Double.")
        }
        
        if let calcMethod = sender.currentTitle {
            switch calcMethod {
            case "+/-":
                displayLabel.text = String(number * -1) // ์™ผ์ชฝ์ด ๋ฌธ์ž์—ด์ด๋ฏ€๋กœ String์œผ๋กœ ํ˜•๋ณ€ํ™˜ ํ•ด์ค˜์•ผ ํ•œ๋‹ค.
                break
            case "AC":
                displayLabel.text = "0"
                break
            case "%":
                displayLabel.text = String(number / 100)
                break
            default:
                break
            }
        }
    }

    
    @IBAction func numButtonPressed(_ sender: UIButton) {
        //What should happen when a number is entered into the keypad
        if let numberValue = sender.currentTitle {
            
            if isFinishedTypingNumber {
                displayLabel.text = numberValue
                isFinishedTypingNumber = false
            }
            else{
                displayLabel.text! += numberValue
            }
        }
    }
}

์—ฐ์‚ฐ๋ฒ„ํŠผ์€ calcButtonPressed ํ•จ์ˆ˜์™€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์–ด์„œ ์—ฌ๊ธฐ์— ๊ตฌํ˜„ํ•˜๋ฉด ๋œ๋‹ค.

 

displayLabel.text ๋ถ€๋ถ„์„ Double ๋กœ ๊ฐ์‹ผ ์ด์œ ๋Š” text ๋ฅผ ์ˆซ์ž๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— Double ๋กœ ๊ฐ•์ œ ํ˜•๋ณ€ํ™˜ ํ•ด์ค€ ๊ฒƒ์ด๋‹ค.

 

๊ฐ•์ œํ˜•๋ณ€ํ™˜ ํ–ˆ์„ ๋•Œ ์—๋Ÿฌ๊ฐ€ ๋‚˜์„œ ์•ฑ์ด ๋ฉˆ์ถ”๋Š” ๊ฒƒ์„ guard ๋ฅผ ์ด์šฉํ•ด์„œ ๋ง‰์•˜๋‹ค. guard ๋ฌธ๋ฒ•์€ if ๋ฌธ๊ณผ ๋™์ผํ•˜์ง€๋งŒ ๋ฌด์กฐ๊ฑด else ๋ฌธ์„ ์จ์„œ critical ์—๋Ÿฌ๋ฅผ ๋ง‰๊ณ  ๋น ๋ฅด๊ฒŒ ์ข…๋ฃŒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. ๋ฐ˜๋“œ์‹œ return ์ด๋‚˜ throw, fatalError ๋“ฑ์„ ๋ช…์‹œํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

 

P.S) +/- ๋ฒ„ํŠผ๊ณผ ์—ฐ๊ฒฐ๋œ ํ•จ์ˆ˜ ๋ณ€๊ฒฝ ํ•„์š”

+/- ๋ฒ„ํŠผ์ด calButtonPressed ์— ๋ฌถ์—ฌ ์žˆ์–ด์„œ ๊ทธ๋ƒฅ ์ˆซ์ž๋ถ€ํ˜ธ๋ฅผ ๋ฐ”๊พธ๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ ์—ฐ์‚ฐ์„ ํ•˜๋ ค๊ณ  ํ•˜๊ธฐ์— ์—๋Ÿฌ๊ฐ€ ๋‚œ๋‹ค.

์—ฐ๊ฒฐ๋œ ํ•จ์ˆ˜๋ฅผ numButtonPressed ํ•จ์ˆ˜๋กœ ๋ฐ”๊ฟ”์ค€๋‹ค. ์ฆ‰ ์—ฐ๊ฒฐ๋œ ๋ฒ„ํŠผํ•จ์ˆ˜๋ฅผ ์ œ๊ฑฐํ•ด์ค€๋‹ค.

๋ฒ„ํŠผ์„ ctrl + ๋“œ๋ž˜๊ทธํ•˜์—ฌ view controller ๋กœ ๊ฐ–๋‹ค๋Œ„๋‹ค.

sent Events ๋ชฉ๋ก ์ค‘์— numButtonPressed ํ•จ์ˆ˜๋ฅผ ์ฒดํฌํ•œ๋‹ค.

calButtonPressed() -> numButtonPressed() ๋กœ ๋ฐ”๊พธ๋ฉด ์ •์ƒ๋™์ž‘ํ•œ๋‹ค.

 

2) .(์†Œ์ˆ˜์ ) ๋ฒ„ํŠผ์„ ๊ตฌํ˜„ํ•ด๋ณด์ž.

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var displayLabel: UILabel!
    private var isFinishedTypingNumber: Bool = true
    
    
    @IBAction func calcButtonPressed(_ sender: UIButton) {
        //What should happen when a non-number button is pressed
        isFinishedTypingNumber = true
        
        guard let number = Double(displayLabel.text!) else {
            fatalError("cannot convert display label text to a Double.")
        }
        
        if let calcMethod = sender.currentTitle {
            switch calcMethod {
            case "+/-":
                displayLabel.text = String(number * -1) // ์™ผ์ชฝ์ด ๋ฌธ์ž์—ด์ด๋ฏ€๋กœ String์œผ๋กœ ํ˜•๋ณ€ํ™˜ ํ•ด์ค˜์•ผ ํ•œ๋‹ค.
                break
            case "AC":
                displayLabel.text = "0"
                break
            case "%":
                displayLabel.text = String(number * 0.01)
                break
            default:
                break
            }
        }
    }

    
    @IBAction func numButtonPressed(_ sender: UIButton) {
        //What should happen when a number is entered into the keypad
        if let numberValue = sender.currentTitle {
            
            if isFinishedTypingNumber {
                displayLabel.text = numberValue
                isFinishedTypingNumber = false
            }
            else{
                switch numberValue {
                case ".":
                    guard let currentDisplayValue = Double(displayLabel.text!) else{
                        fatalError("Cannot convert display label text to a Double !")
                    }
                    let isInt = floor(currentDisplayValue) == currentDisplayValue
                    
                    if !isInt{
                        return
                    }
                    break
                default:
                    break
                }
                displayLabel.text! += numberValue
            }
        }
    }
}

numButtonPressed ํ•จ์ˆ˜์—์„œ ๊ตฌํ˜„ํ•ด์คฌ๋‹ค. ์ •์ˆ˜๋ฉด ์†Œ์ˆ˜๋กœ ๋ฐ”๊พธ๊ณ  ์†Œ์ˆ˜๋ฉด return.

 

P.S) command + option + ์™ผ์ชฝํ™”์‚ดํ‘œ๋ฅผ ๋ˆ„๋ฅด๋ฉด ์ฝ”๋“œ๋ฅผ ์ ‘์„ ์ˆ˜ ์žˆ๋‹ค.

 

3) ์•ž์—์„œ ๋ฐฐ์šด getter์™€ setter๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ฝ”๋“œ ๋ฆฌํŒฉํ† ๋ง์„ ํ•ด๋ณด์ž.

guard let number ๋ถ€๋ถ„๊ณผ guard let currentDisplayValue ๋ถ€๋ถ„์ด ์ค‘๋ณต๋œ๋‹ค.

์ด ๋ถ€๋ถ„์„ ์ „์—ญ๋ณ€์ˆ˜๋กœ ๋นผ์„œ ๋ณ€์ˆ˜ get ์†์„ฑ์œผ๋กœ ๊ฐ€์ ธ์˜ค์ž.

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var displayLabel: UILabel!
    private var isFinishedTypingNumber: Bool = true
    
    private var displayValue: Double {
        get {
            guard let currentDisplayValue = Double(displayLabel.text!) else {
                fatalError("cannot convert display label text to a Double.")
            }
            return currentDisplayValue
        }
    }
    
    @IBAction func calcButtonPressed(_ sender: UIButton) {
        //What should happen when a non-number button is pressed
        isFinishedTypingNumber = true
        
        if let calcMethod = sender.currentTitle {
            switch calcMethod {
            case "+/-":
                displayLabel.text = String(displayValue * -1) // ์™ผ์ชฝ์ด ๋ฌธ์ž์—ด์ด๋ฏ€๋กœ String์œผ๋กœ ํ˜•๋ณ€ํ™˜ ํ•ด์ค˜์•ผ ํ•œ๋‹ค.
                break
            case "AC":
                displayLabel.text = "0"
                break
            case "%":
                displayLabel.text = String(displayValue * 0.01)
                break
            default:
                break
            }
        }
    }

    
    @IBAction func numButtonPressed(_ sender: UIButton) {
        //What should happen when a number is entered into the keypad
        if let numberValue = sender.currentTitle {
            
            if isFinishedTypingNumber {
                displayLabel.text = numberValue
                isFinishedTypingNumber = false
            }
            else{
                switch numberValue {
                case ".":
                    let isInt = floor(displayValue) == displayValue
                    
                    if !isInt{
                        return
                    }
                    break
                default:
                    break
                }
                displayLabel.text! += numberValue
            }
        }
    }
}

์ฝ”๋“œ์ •๋ฆฌ๋ฅผ ์™„๋ฃŒํ•œ ๋ชจ์Šต.

 

๋˜ํ•œ displayValue ๊ฐ’์„ ๊ฐ€์ ธ์™€์„œ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•ด์„œ displayLabel.text ๋กœ ๋„ฃ๋Š” ๋ถ€๋ถ„์„

set ๋ฅผ ์ด์šฉํ•ด์„œ displayValue ๊ฐ’์ด ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ์ž๋™์œผ๋กœ displayLabel ๊ฐ’์„ ๊ฐฑ์‹ ํ•ด์ฃผ์ž.

 

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var displayLabel: UILabel!
    private var isFinishedTypingNumber: Bool = true
    
    private var displayValue: Double {
        get {
            guard let currentDisplayValue = Double(displayLabel.text!) else {
                fatalError("cannot convert display label text to a Double.")
            }
            return currentDisplayValue
        }
        set {
            displayLabel.text = String(newValue)
        }
    }
    
    @IBAction func calcButtonPressed(_ sender: UIButton) {
        //What should happen when a non-number button is pressed
        isFinishedTypingNumber = true
        
        if let calcMethod = sender.currentTitle {
            switch calcMethod {
            case "+/-":
                displayValue *= -1
                break
            case "AC":
                displayLabel.text = "0"
                break
            case "%":
                displayValue *= 0.01
                break
            default:
                break
            }
        }
    }

    
    @IBAction func numButtonPressed(_ sender: UIButton) {
        //What should happen when a number is entered into the keypad
        if let numberValue = sender.currentTitle {
            
            if isFinishedTypingNumber {
                displayLabel.text = numberValue
                isFinishedTypingNumber = false
            }
            else{
                switch numberValue {
                case ".":
                    let isInt = floor(displayValue) == displayValue
                    
                    if !isInt{
                        return
                    }
                    break
                default:
                    break
                }
                displayLabel.text! += numberValue
            }
        }
    }
}

displayValue *= -1

displayValue *= 0.01

์ฝ”๋“œ๊ฐ€ ์ด๋ ‡๊ฒŒ ๊ฐ„๋‹จํ•ด์กŒ๋‹ค.

 

4) MVC ๋””์ž์ธ ํŒจํ„ด๋„ ์ ์šฉํ•ด๋ณด์ž.

MVC ๊ตฌ์กฐ๋ฅผ ์œ„ํ•ด Model, View, Controller ํด๋”๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๊ณ  Model ์—ญํ• ์„ ํ•  CalculatorLogic.swift ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด์ค€๋‹ค.

์ด ๋•Œ, View ํด๋”์—๋Š” Main storyboard ๋ฅผ ๋„ฃ์–ด์ฃผ๊ณ  Controller ํด๋”์—๋Š” ViewController.swift ํŒŒ์ผ์„ ๋„ฃ์–ด์ฃผ์ž.

 

ํ˜„์žฌ๋Š” ์œ„์™€ ๊ฐ™์ด View ๋‹จ์ธ ViewController.swift ์— ๋ชจ๋“  ์ฝ”๋“œ๊ฐ€ ๋“ค์–ด ์žˆ๋‹ค.

์—ฌ๊ธฐ์„œ ๊ณ„์‚ฐ ์ฝ”๋“œ๋ฅผ ๋นผ์„œ Model ๋‹จ์ธ Calculator.swift ํŒŒ์ผ๋กœ ์˜ฎ๊ฒจ์ฃผ์ž.

 

CalculatorLogic.swift

import Foundation

class CalculatorLogic {
    
    var number: Double
    
    init(number: Double){
        self.number = number
    }
    
    //return ๊ฐ’์ด double ํ˜•์ด ์•„๋‹ ๊ฒฝ์šฐ๋ฅผ ์œ„ํ•ด optional ์ถ”๊ฐ€ํ•ด์คŒ.
    func calculate(symbol: String) -> Double? {
        switch symbol {
        case "+/-":
            return number * -1
        case "AC":
            return 0
        case "%":
            return number * 0.01
        default:
            return nil
        }
    }
}

CalculatorLogic ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๊ณ  ๊ณ„์‚ฐ์— ํ•„์š”ํ•œ ์ˆซ์ž๋ฅผ number ๋กœ ๊ฐ–๊ณ  ์žˆ๊ฒŒ ํ–ˆ๋‹ค.

init ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์„œ number ๊ฐ’์ด CalculatorLogic ๊ฐ์ฒด๊ฐ€ ํ˜ธ์ถœ ๋  ๋•Œ ์ ์šฉ๋˜๋„๋ก ํ•˜์ž.

 

calculate ํ•จ์ˆ˜๊ฐ€ ViewController ํด๋ž˜์Šค์— ์žˆ๋˜ calcButton ํ•จ์ˆ˜๋ถ€๋ถ„์ด๋‹ค.

symbol(๊ณ„์‚ฐ ๋ถ€ํ˜ธ)๋ฅผ ๋งŒ๋‚˜๋ฉด number ๊ฐ’์— ์—ฐ์‚ฐ์„ ํ•ด์„œ return ํ•œ๋‹ค.

์ด๋•Œ, return ๊ฐ’์ด double ํ˜•์ด ์•„๋‹ ๊ฒฝ์šฐ๋ฅผ ์œ„ํ•ด ?(optional) ๋ฅผ ์ถ”๊ฐ€ํ•ด์ค˜์•ผ ํ•œ๋‹ค. default return ์€ nil !

 

 

ViewController.swift

    @IBAction func calcButtonPressed(_ sender: UIButton) {
        
        //What should happen when a non-number button is pressed
        
        isFinishedTypingNumber = true
        
        if let calcMethod = sender.currentTitle {
            
            let calculator = CalculatorLogic(number: displayValue)
            
            guard let result = calculator.calculate(symbol: calcMethod) else {
                fatalError("The result of the calculation is nil.")
            }
            displayValue = result
        }
    }

viewController ํด๋ž˜์Šค์˜ ์›๋ž˜ calcButtonPressed ํ•จ์ˆ˜์—์„  ์œ„์™€ ๊ฐ™์ด CalculatorLogic ํด๋ž˜์Šค๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  CalculatorLogic ํด๋ž˜์Šค์˜ calculate ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

CalculatorLogic ๊ฐ์ฒด ์„ ์–ธ ์‹œ number ๊ฐ’์œผ๋กœ displayValue ๋ฅผ ์ „๋‹ฌํ•œ๋‹ค.

calculate ํ•จ์ˆ˜์— calcMethod ๊ฐ’์„ symbol ์— ๋„˜๊ฒจ์ฃผ๊ณ  ์—ฐ์‚ฐํ•˜๊ฒŒ ํ•œ๋‹ค.

 

์ด ๋•Œ, calculate ํ•จ์ˆ˜์˜ ๊ฒฐ๊ณผ๊ฐ’์ด ์—†๊ฑฐ๋‚˜ ์—๋Ÿฌ๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ๋ฅผ ๋Œ€๋น„ํ•˜์—ฌ guard else ๋ฌธ์„ ์‚ฌ์šฉํ•ด์ค€๋‹ค.

 

5) CalculatorLogic ํด๋ž˜์Šค๋ฅผ Struct ๋กœ ๋ฐ”๊พธ์ž

import Foundation

struct CalculatorLogic {
    
    private var number: Double?
    
    mutating func setNumber(_ number: Double){
        self.number = number
    }
    
     func calculate(symbol: String) -> Double? {
         if let n = number {
             switch symbol {
             case "+/-":
                 return n * -1
             case "AC":
                 return 0
             case "%":
                 return n * 0.01
             default:
                 return nil
             }
         }
         return nil
    }
}

CalculatorLogic ํด๋ž˜์Šค๋ฅผ Struct ๋กœ ๋ฐ”๊ฟจ๋‹ค. Struct ๋กœ ๋ฐ”๊พธ๋ฉด์„œ ํ•„์š”์—†๋Š” init ํ•จ์ˆ˜๋ฅผ ์ง€์› ๋‹ค.

 

struct ์ „์—ญ๋ณ€์ˆ˜๋Š” ํ•ญ์ƒ private access level ์„ ๊ฐ–๊ณ  ์žˆ๊ฒŒ ํ•˜๋Š”๊ฒŒ ์ข‹๋‹ค. number ๊ฐ’์€ setNumber ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด์„œ๋งŒ ๋ณ€๊ฒฝ๋˜๋„๋ก ๊ฐ์‹ธ์ž. ์ด ๋•Œ, mutating ํ‚ค์›Œ๋“œ๋กœ ์ „์—ญ๋ณ€์ˆ˜๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ํ•จ์ˆ˜์ž„์„ ๋ช…์‹œํ•ด์ฃผ์ž.

 

number ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ(์‚ฌ์šฉ์ž๊ฐ€ ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ•˜์ง€ ์•Š์•˜์„ ๋•Œ)์—” ์—ฐ์‚ฐ์„ ํ•˜์ง€ ๋ง์•„์•ผ ํ•˜๋ฏ€๋กœ if ๋ฌธ์„ ์ถ”๊ฐ€ํ•ด์ฃผ์—ˆ๋‹ค.

    private var calculator = CalculatorLogic()

    @IBAction func calcButtonPressed(_ sender: UIButton) {
        
        //What should happen when a non-number button is pressed
        
        isFinishedTypingNumber = true
        calculator.setNumber(displayValue)
        
        if let calcMethod = sender.currentTitle {
            
            guard let result = calculator.calculate(symbol: calcMethod) else {
                fatalError("The result of the calculation is nil.")
            }
            displayValue = result
        }
    }

CalculatorLogic Class ๊ฐ€ ์•„๋‹Œ CalculatorLogic Struct ๋Š” ์œ„์™€ ๊ฐ™์ด ์„ ์–ธ ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์„ ์–ธํ•˜๊ณ  setNumber ํ•จ์ˆ˜๋กœ ๊ฐ’์„ ๋„ฃ์–ด์„œ ์ดˆ๊ธฐํ™”ํ•˜์ž.

 

6) CalculatorLogic ํด๋ž˜์Šค์— Tuple ์„ ์ ์šฉํ•ด๋ณด์ž.

import Foundation

struct CalculatorLogic {
    
    private var number: Double?
    private var intermediateCalculation: (n1: Double, calcMethod: String)?

    mutating func setNumber(_ number: Double){
        self.number = number
    }
    
     mutating func calculate(symbol: String) -> Double? {
         
         if let n = number {
             switch symbol {
             case "+/-":
                 return n * -1
             case "AC":
                 return 0
             case "%":
                 return n * 0.01
             case "=":
                 return performTwoNumCalculation(n2: n)
             default:
                 intermediateCalculation = (n1: n, calcMethod: symbol)
             }
         }
         return nil
    }
    
    private func performTwoNumCalculation(n2: Double) -> Double{
        if let n1 = intermediateCalculation?.n1,
           let operation = intermediateCalculation?.calcMethod {
            
            switch operation {
            case "+":
                return n1 + n2
            case "-":
                return n1 - n2
            case "x":
                return n1 * n2
            case "÷":
                return n1 / n2
            default:
                fatalError("The operation passed in does not match any of the cases.")
            }
        }
        return 0.0
    }
}

์ˆซ์ž์™€ ์ˆ˜์‹ ๋ฌธ์ž์—ด์„ ๋‹ด๋Š” intermediateCalculation ํŠœํ”Œ ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•ด์ฃผ์ž

์ด ๋ณ€์ˆ˜๊ฐ€ ๊ฐ’์ด ์—†์„ ๊ฒฝ์šฐ๊ฐ€ ์žˆ๊ธฐ์— optional(?) ์„ ์ถ”๊ฐ€ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

 

calculate(symbol: String) ํ•จ์ˆ˜์—์„œ +/-, AC, %, = ๊ธฐํ˜ธ๊ฐ€ ์•„๋‹Œ +, -, x, ÷ ๊ธฐํ˜ธ์ด๋ฉด ๋‘ ์ˆซ์ž์˜ ์—ฐ์‚ฐ์ด ํ•„์š”ํ•˜๋ฏ€๋กœperformTwoNumCalculation ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์„œ ์—ฐ์‚ฐํ•ด์„œ ๊ฐ’์„ return ํ•˜์ž.

 

performTwoNumCalculation ํ•จ์ˆ˜์— n2 ๊ฐ’์„ ์ „๋‹ฌํ•˜๊ณ  intermediateCalculation ํŠœํ”Œ ๋ณ€์ˆ˜์— ์ €์žฅ๋œ n1 ์ˆซ์ž์™€ ์ˆ˜์‹๊ธฐํ˜ธ์™€ ํ•จ๊ป˜ ๊ณ„์‚ฐํ•ด์ค€๋‹ค. ์ด ๋•Œ, default ๋ฌธ์—๋Š” ํŠน์ • ๊ฐ’์„ ๋ณด๋‚ด๊ธฐ๋ณด๋‹ค fatalError๋ฅผ ๋ฟŒ๋ ค์„œ ์น˜๋ช…์ ์ธ ์—๋Ÿฌ๋ฅผ ๋ง‰์ž.

    @IBAction func calcButtonPressed(_ sender: UIButton) {
        
        //What should happen when a non-number button is pressed
        
        isFinishedTypingNumber = true
        calculator.setNumber(displayValue)
        
        if let calcMethod = sender.currentTitle {
//            guard let result = calculator.calculate(symbol: calcMethod) else {
//                fatalError("The result of the calculation is nil.")
//            }
            if let result = calculator.calculate(symbol: calcMethod) {
                displayValue = result
            }
        }
    }

ViewController ํด๋ž˜์Šค์˜ calcButtonPressed ํ•จ์ˆ˜ ๋‚ด์˜ guard let ๊ตฌ๋ฌธ์„ if let ์œผ๋กœ ๋ฐ”๊ฟ”์ฃผ์ž.

 

guard let ์กฐ๊ฑด๋ฌธ์€ ๋ชจ๋“  ์˜ˆ์™ธ์‚ฌํ•ญ์— cash ๋ฅผ ๋‚ธ๋‹ค. 

if let ์กฐ๊ฑด๋ฌธ์€ ์‚ฌ์šฉ์ž๊ฐ€ ์ด์ „ ์ˆซ์ž๋‚˜ ์—ฐ์‚ฐ์—†์ด ์‹ค์ˆ˜๋กœ = ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €๋‹ค๋ฉด crash ๋‚˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ ๊ทธ๋ƒฅ ์ฝ”๋“œ๋ฅผ ๋ฌด์‹œํ•œ๋‹ค.

 

๋”ฐ๋ผ์„œ ์ด ์ƒํ™ฉ์—์„  guard let ์ด ๊ตฌ์ง€ ํ•„์š”์—†๊ณ  if let ๊ตฌ๋ฌธ์ด ๋” ๋งž๋‹ค.

์ตœ์ข… ์•ฑ.

728x90