본문 바로가기
ios 뽀개기/ios 응용해보기

아이폰 계산기 3번째 포스팅

by 인생여희 2017. 12. 5.
반응형

//

//  CalculatorBrain.swift

//  Calulatoer2

//

//  Created by MacBookPro on 2017. 12. 5..

//  Copyright © 2017년 MacBookPro. All rights reserved.

//

// 모델부분은 Foundation으로 임포트 한다.

import Foundation


/* 옵셔널 생긴거

 enum Optional<T>{

 case None

 case Sone(T)

 }

 */

//곱셈 함수

func multiply(op1: Double, op2: Double) ->Double{

    return op1 * op2

}


class CalculatorBrain

{

    //값들이 누적해서 더해진 결과값

    private var accumulator = 0.0

    

    //컨트롤러에서 값을 인자로 넘겨주면 값을 accumulator로 할당한다.

    func setOperation(operand: Double){ //

        accumulator = operand

    }

    

    //step2

    //연산 기호 사전 만들기

    //value값을 더블이 들어갈 수도 있고,함수가 들어갈 수도 있게 enum 사용!

    var operations: Dictionary<String,Operation> = [

        "π": Operation.Constant(M_PI), //옵셔널 연결 시키기

        "𝐞": Operation.Constant(M_E), //m_e

        "√": Operation.UnaryOperation(sqrt), //sqrt 스퀘어 루트를 만들기 위한 단항연산의 연관값은 함수다!

        "cos": Operation.UnaryOperation(cos), //cos

        "×" : Operation.BinaryOperation(multiply)

    ]

    

    //enum은 개별 값들의 모음

    //클래스 처럼 메소드를 가질 수 있다

    //저장 변수를 가질 수 없다. case가 각 값이다. 계산변수는 가질 수 있다.

    //상속을 받거나 상속 할 수 없다.

    //값으로 전달될 수 있다.

    // step1

    enum Operation {

        case Constant(Double) //상수

        case UnaryOperation((Double)->Double) //단항연산  / 더블을 받아서 더블을 리턴하는 함수, 이게 단항연산의 연관값인 함수다

        case BinaryOperation((Double,Double)-> Double) //이항 연산 / 두개의 더블을 받아서 더블을 리턴하는 함수 가 연관값이다.

        case Equals // =

    }

    

    

    

    //step3

    //컨트롤러에서 호출한 뒤 매개변수를 넘겨주면 심볼값을 대조한뒤 해당 연산을 accumulator에 대입해준다.

    func performOperation(symbol: String){

        //컨트롤러에서 호출하고 넘겨준 값으로 딕셔너리에 가서 찾는다.

        if let operation = operations[symbol]{

            

            switch operation{

            //위에 딕셔너리에서 연관 값 빼오기

            case .Constant(let associatedConstantValue):

                accumulator = associatedConstantValue

            case .UnaryOperation(let fun):

                accumulator = fun(accumulator)

            case .BinaryOperation(let fun):

                executePendingBinaryOperation()

                pending = PendingBinaryOperationInfo(binaryFunction:fun, firstOperation:accumulator)

            case .Equals:

                executePendingBinaryOperation()

                

                //if pending != nil {

                    //accumulator = pending!.binaryFunction(pending!.firstOperation, accumulator)

                    //pending = nil

                //}

            }

        }

    }

    

    //같다 = 이 눌러지면 호출

    private func executePendingBinaryOperation(){

        if pending != nil {

            accumulator = pending!.binaryFunction(pending!.firstOperation, accumulator)

        }

    }

    

    private var pending: PendingBinaryOperationInfo?

    

    //이항연산을 해주기 위해서 구조체 선언(값 저장 및 계산 가능)

    struct  PendingBinaryOperationInfo {

        var binaryFunction: (Double , Double) -> Double

        var firstOperation: Double

    }

    

    //읽기전용 프로퍼티

    var result: Double {

        get {

            return accumulator

        }

        

    }

}

반응형

댓글