ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 200916 - TIL
    TIL/2021 2020. 9. 17. 00:46

    Swift 문법

     

    programming paradigm에 대해서 아주 간단히 공부했다.

    스위프트는

    1. Object Oriented Programming

    2. Functional  Programming

    3. Protocol Oriented Programming

    을 사용하는 Multi paradigm 언어이다. 객체지향과 함수형 프로그래밍은 Youtube를 통해 개념을 간단히 본 적이 있지만 프로토콜 지향 프로그래밍은 본 적이 없었다. 해당 패러다임에 대해서 간단히 알아봐야겠다.

     

     

     

    Object Oriented Paradigm의 주요 개념에 대해 간단하게 공부했다.

    • Object
    • Abstraction
    • Class

     

     

     

     

    Structure와 Class에 대해서 공부했다.

    • Instance
    • Method
    • Initializer
    • Value Type vs Reference Type
    • Identity Operator ( ===, !==)
    • Nested Type

    구조체는 값 형식이고 클래스는 참조 형식이다. 값 형식은 복사본을 넘겨주어 새로운 메모리에 생성하는 것이고 참조 형식은 주소를 넘겨주어서 값을 바꾸게 되면 원본에도 영향을 끼친다.

     

    이렇게 원본이 바뀌게 되면 좋은 점이 없을 거 같다는 생각이 든다.

     

    아직 상속이나 소멸자에 대해서는 공부하지 않았다.

     

    Nested Type을 사용하는 이유에 대해서 아직 와 닿지 않았다. 그 부분을 좀 더 자세히 봐야겠다.

     

     

     

     

     

     

    Property에 대해서 공부했다.

    • Stored Property
    • Lazy Stored Property
    • Computed Property
    • Getter
    • Setter
    • Property Observer
    • Type Property
    • self, super

    저장 프로퍼티는 나름 이해가 잘됐는데 연산 프로퍼티는 아직 완전한 이해가 되지 않았다. 여러 번 반복하며 개념을 확실하게 알아가야겠다.

     

     

     

     

    Method와 Subscript에 대해서 공부했다.

    • Instance Method
    • Type Method
    • Subscript
    • Dynamic Member Lookup

    method에도 종류가 나뉘는 것을 알았다. 접근하는 방법도 달랐다.

    subscript도 이해가 완벽하게 되지 않았다.

     

     

     

     

     

    iOS

    커서 문제를 해결했다.

     

    커서가 옮겨지지 않는 이유를 알았다.

    becomeFirstResponder() 메서드가 문제인지 알고 개발자 문서에서 다른 메서드를 찾아보고 했는데 문제는 순서였다.

    centerField.becomeFirstResponder()
    presentAlert(title: "⚠️", message: "지원하지 않는 연산자 입니다.\n올바른 연산자( +, -, *, / )를\n 입력해주세요." )

    순서를 위아래만 바꾸니 정상적으로 작동했다.

    경고창이 뜬 상태에서는 화면이 작동이 안 되므로 커서를 옮기는 메서드를 경고창 앞에 작성해야 한다.

     

     

     

     

     

    class ViewController: UIViewController {
        
        @IBOutlet weak var leftField: UITextField!
        
        @IBOutlet weak var centerField: UITextField!
        
        @IBOutlet weak var rightField: UITextField!
        
        //경고창 출력 함수
        func presentAlert(title: String, message: String) {
            let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
            
            let okAction = UIAlertAction(title: "확인", style: .default)
            alert.addAction(okAction)
            
            present(alert, animated: true)
        }
        
        
        //초기화 함수
        //만들었지만 한번밖에 안쓰여서 실용성이 없어보여 굳이 해야하는지 의문
        func resetNumber() {
            leftField.text = nil
            rightField.text = nil
            centerField.text = nil
        }
        
        
        
        
        @IBAction func calc(_ sender: Any) {
            
            
            
            
            guard let leftStr = leftField.text, let leftNum = Double(leftStr) else {
                leftField.becomeFirstResponder()
                presentAlert(title: "⚠️", message: "왼쪽 칸에 숫자를 입력해주세요.")
                return
            }
            
            
            guard let rightStr = rightField.text, let rightNum = Double(rightStr)  else {
                rightField.becomeFirstResponder()
                presentAlert(title: "⚠️", message: "오른쪽 칸에 숫자를 입력해주세요.")
                return
            }
            
            guard let op = centerField.text else {
            	centerField.becomeFirstResponder()
                presentAlert(title: "⚠️", message: "올바른 연산자( +, -, *, / )를\n 입력해주세요." )
                return
            }
            var result: Double = 0
            
            //message에 들어갈 문자열 생성 함수
            func makeMsg(op: String, point: Int ) -> String {
                let msg = "\(String(format: "%.0f", leftNum)) \(op) \(String(format: "%.0f", rightNum)) = \(String(format: "%.\(point)f", result))"
                return msg
            }
            
            
            
            switch op {
            case "+":
                result = leftNum + rightNum
                presentAlert(title: "결과", message: makeMsg(op: op, point: 0))
            case "-":
                result = leftNum - rightNum
                presentAlert(title: "결과", message: makeMsg(op: op, point: 0))
            case "*":
                result = leftNum * rightNum
                presentAlert(title: "결과", message: makeMsg(op: "X", point: 0))
            case "/":
                result = leftNum / rightNum
                presentAlert(title: "결과", message: makeMsg(op: "÷", point: 2))
            default:
                centerField.becomeFirstResponder()
                presentAlert(title: "⚠️", message: "지원하지 않는 연산자 입니다.\n올바른 연산자( +, -, *, / )를\n 입력해주세요." )
                centerField.text = nil
                return
            }
            
            resetNumber()
            leftField.becomeFirstResponder()
            
            //기존에 여기서 마지막에 리셋이 있어서 지원하지 않는 연산자를 입력할 경우에도 리셋이 된다.
            //왼쪽,오른쪽 연산자값이 모두 바인딩 되면  리셋을 하고 싶어서 여러가지 방법을 생각해보았다.
        
            //문제가 switch문에서 break를 하면 switch문만 빠져나오는게 문제였는데 메서드안에 구현됐으니 혹시 return을 하면 아래 코드가 실행 안되고 메서드가 종료되지 않을까 하고 return으로 변경하니 아래코드가 실행이 안됐다. 그래서 bindingSuccess = false 도, 아래 주석처리된 코드도 필요가 없어졌다.
            
            //커서문제를 계속 고민해봤는데 아직도 고치지 못했다.
            //becomeFirstResponder()메서드의 문제인가해서 개발문서를 읽어보니 Calling this method is not a guarantee that the object will become the first responder. 보장하지 않는다고 나와있는데 커서문제에 대한 말로 이해했고 바꾸고 싶다면 custom responders에서 override해서 사용할수 있다고 나와있는거 같은데 이에 대한 강의를 아직 듣지 못해서 바꾸지 못했다.
            //순서가 문제였다.
            
            // 나눗셈에서 버려지는 수가 생겨서 Double로 입력을 받고 결과값만 소숫점 2번쨰 자리까지 나오게 구현했다.
            // 곱셈을 할땐 출력창에 X로 나눗셈을 할땐 출력창에 ÷ 을 출력하고 싶었고, 덧셈,뺼셈,곱셈은 출력창에 소숫점이 안나오게, 나머지만 소숫점이 나오게 출력하고 싶었는데 switch 분기할때마다 결과값을 각각 넣는 코드를 생각했다가 그럼 msg 생성코드가 계속 반복이 돼서 함수로 구현을 했는데 함수선언 위치를 위에 올려 메서드로 생성을 하면 옵셔널바인딩한 leftNum, rightNum 을 인식하지못해서 nested func으로 구현을 했는데 함수선언위치가 여기 있어도 괜찮은지 의문이다.
            // 커서문제를 제외하고 원하는 대로 구현은 됐는데 코드의 가독성이나 좋은 알고리즘인가에 대해서는 잘모르겠다.
     
        }
        
        override func viewDidLoad() {
            super.viewDidLoad()
            
            
            
            // Do any additional setup after loading the view.
        }
        
        
    }
    

    사용자에게 익숙한 연산자가 보이도록 하고 나머지는 소수점으로 출력하고 나머지는 정수만 출력하도록 표시하고 싶어서 switch로 분기시켰다.

    makeMsg함수의 위치가 거슬렸다. 메서드로 만들고 싶었는데 안에 있는 leftNum, rightNum 때문에 다른 메서드들과 같은 스코프에서 선언이 불가능했다. 어쩔 수 없이 Nested 함수로 선언했다.

     

    소수점 보여주는 코드가 조금 복잡해 보이는데 

    String(format:arguments:)

    이 메서드를 이용하는 방법 말고 다른 방법은 못 찾았다.

     

    728x90

    'TIL > 2021' 카테고리의 다른 글

    200918 - TIL  (1) 2020.09.19
    200917 - TIL  (1) 2020.09.18
    200914 - TIL  (0) 2020.09.15
    200910 - TIL  (0) 2020.09.15
    200909 - TIL  (0) 2020.09.15
Designed by Tistory.