[내일배움캠프 16일차] Chapter 2 과제 피드백 & Chapter 3 시작!

NH·2025년 3월 24일
0

내일배움캠프_iOS

목록 보기
15/24
post-thumbnail

📌 Today I Learned (TIL) - 숫자야구게임 코드 개선, 앱 개발 강의

오늘은 제출한 숫자야구게임 과제 피드백을 보고 코드 개선을 하였다.
또한 새로운 챕터를 시작하며, 강의를 듣고 정리한 내용을 공유한다.


Chapter 2 숫자야구게임 과제 피드백

💁 튜터님 개선 피드백

1️⃣ 첫번째 개선 피드백

  • mainMenu 메소드에서 isQuit가 있는데 isQuit를 사용하지 않고 return으로 함수를 종료해도 괜찮을 것 같아요.

내가 구현한 방법

while문 안에 Switch 문에서 break 문을 사용해도 while문 탈출이 안됨
Bool 타입의 isQuit 변수를 사용해 아래와 같이 구현

  • 코드
    func mainMenu() {
            var isQuit: Bool = true // 기존 - 게임 반복 여부 저장 변수
            var gameCount: Int = 0
            var logArray: [String] = []
           
            while isQuit {
                message.menu()
               
                switch readLine() ?? "" {
                case "1":
                    var tryCount = startGame()
                   
                    gameCount += 1
    
                    logArray.append(log.gameLog(gameCount, tryCount))
                   
                    tryCount = 0 // 시도 횟수 초기화
                case "2":
                    print("< 게임 기록 보기 >")
                    message.gameLog(logArray)
                case "3":
                    print("Bye!")
                    isQuit = false // 기존 - 반복문 종료
                default:
                    print("올바른 번호를 입력해주세요.")
                }
            }
        }

튜터님이 주신 피드백 적용

기존 isQuit 변수를 삭제하고, return 문을 사용하여, 반복문을 탈출하도록 개선 완료!

  • 코드
    func mainMenu() {
            var gameCount: Int = 0
            var logArray: [String] = []
           
            while true { // 개선 후 - isQuit 변수 삭제 및 기본 true 조건
                message.menu()
               
                switch readLine() ?? "" {
                case "1":
                    var tryCount = startGame()
                   
                    gameCount += 1
    
                    logArray.append(log.gameLog(gameCount, tryCount))
                   
                    tryCount = 0
                case "2":
                    print("< 게임 기록 보기 >")
                    message.gameLog(logArray)
                case "3":
                    print("Bye!")
                    return // 개선후 - 반복문 종료, 기존 isQuit 변수 삭제 및 return 문으로 반복문 탈출
                default:
                    print("올바른 번호를 입력해주세요.")
                }
            }
        }

2️⃣ 두번째 개선 피드백

BaseballGame 클래스의 84번째 줄에 print("")가 있는데 해당 부분도 message 클래스에서 newLine 메소드로 구현해도 좋았을 것 같아요.

내가 구현한 방법

줄바꿈을 위해 print 문으로 빈 문자열 출력

  • 코드

    while true {
    	message.input()
               
    	tryCount += 1
    
    	let userAnswer = userInput.getUserInput()
    	let gameResult = checkAnswer.check(gameAnswer, userAnswer)
               
    	if gameResult.strike == 3 {
    		message.success()
    		break
    	} else if gameResult.strike == 0 && gameResult.ball == 0 {
    		message.lose()
    	} else {
    		message.resultMessage(strike: gameResult.strike, ball: gameResult.ball)
    	}
    		print("") // 기존 - 줄바꿈
    }

튜터님이 주신 피드백 적용

print 기능을 담당하는 Struct에 줄바꿈 기능 메소드를 추가하고, 해당 매소드를 사용하는 방식으로 개선 완료!

  • 코드

    while true {
    	message.input()
               
    	tryCount += 1
    
    	let userAnswer = userInput.getUserInput()
    	let gameResult = checkAnswer.check(gameAnswer, userAnswer)
               
    	if gameResult.strike == 3 {
    		message.success()
    		break
    	} else if gameResult.strike == 0 && gameResult.ball == 0 {
    		message.lose()
    	} else {
    		message.resultMessage(strike: gameResult.strike, ball: gameResult.ball)
    	}
    		message.newLine() // 개선 후 - 줄바꿈, Print문 구현이 아닌, PrintMessage의 메소드로 기능 구현
    }
  • print 기능 구조체에 줄바꿈 메소드 추가

    protocol PrintMessageProtocol {
       func menu()
       func newLine()
       func start()
       func input()
       func success()
       func lose()
       func resultMessage(strike: Int, ball: Int)
       func gameLog(_ gameLog: [String])
    }
    
    /**
    출력 기능 담당하는 구조체
    */
    struct PrintMessage: PrintMessageProtocol {
    	// 줄바꿈 기능
       func newLine() {
           print("")
       }

🔹 객체지향 프로그래밍(OOP)의 4가지 특징

Swift는 객체지향 프로그래밍(Object-Oriented Programming, OOP)을 지원하는 언어이다.
객체지향의 핵심 개념 4가지를 이해하면 더 효율적이고 확장성 있는 코드를 작성할 수 있다.

1️⃣ 상속(Inheritance)

  • 부모 클래스의 속성과 메서드를 자식 클래스가 물려받아 사용할 수 있음

  • 코드 재사용성을 높이고, 유지보수를 쉽게 할 수 있음

  • Swift에서 class를 사용하여 상속을 구현

    class Animal {
        func sound() {
            print("소리를 냅니다.")
        }
    }
    
    class Dog: Animal {
        override func sound() {
            print("멍멍!")
        }
    }
    
    let myDog = Dog()
    myDog.sound()  // 출력: 멍멍!

2️⃣ 캡슐화(Encapsulation)

  • 객체의 속성과 메서드를 외부에서 접근하지 못하도록 보호하는 개념

  • private, public, internal 등의 접근 제어자를 활용하여 구현

    class Person {
        private var name: String = "John"
    
        func getName() -> String {
            return name
        }
    }
    
    let person = Person()
    print(person.getName())  // 정상 출력: John
    // print(person.name)  // 오류 발생 (private 접근 불가)

3️⃣ 다형성(Polymorphism)

  • 같은 메서드를 호출하더라도 객체에 따라 다른 동작을 하도록 하는 개념

  • 메서드 오버라이딩(Method Overriding)을 통해 구현

    class Shape {
        func draw() {
            print("도형을 그립니다.")
        }
    }
    
    class Circle: Shape {
        override func draw() {
            print("원을 그립니다.")
        }
    }
    
    let shape1: Shape = Shape()
    let shape2: Shape = Circle()
    
    shape1.draw()  // 출력: 도형을 그립니다.
    shape2.draw()  // 출력: 원을 그립니다.

4️⃣ 추상화(Abstraction)

  • 불필요한 부분은 숨기고, 중요한 부분만 노출하는 개념

  • 프로토콜(protocol)을 활용하여 구현 가능

    protocol Vehicle {
        func move()
    }
    
    class Car: Vehicle {
        func move() {
            print("자동차가 달립니다.")
        }
    }
    
    let myCar: Vehicle = Car()
    myCar.move()  // 출력: 자동차가 달립니다.

객체지향 프로그래밍을 활용하면

  • 코드 재사용이 가능하고 유지보수가 쉬움
  • 보안성이 높아짐 (캡슐화)
  • 유연한 설계를 통해 확장성이 좋아짐

오늘 강의로 배운 내용

객체지향의 4가지 특징에 대해서도 공부해보시면 좋을것 같습니다. (상속, 캡슐화, 다형성, 추상화)

iOS 앱 생명주기

앱이 실행되고 종료될 때까지의 과정을 앱 생명주기(App Life Cycle)라고 한다.
이 과정을 이해하면 앱의 상태 변화에 따라 적절한 처리를 할 수 있다.

🔹 앱 생명주기의 주요 상태

  1. Not Running: 앱이 실행되지 않은 상태
  2. Inactive: 앱이 활성화되었지만, 이벤트를 받지 않는 상태
  3. Active: 앱이 실행 중이며, 사용자 입력을 받는 상태
  4. Background: 앱이 백그라운드에서 실행 중인 상태
  5. Suspended: 백그라운드에서 멈춰 있는 상태 (필요할 경우 iOS가 앱을 종료할 수도 있음)

AppDelegate & SceneDelegate

앱의 생명주기를 관리하는 두 가지 중요한 클래스가 있다.

🔹 AppDelegate

  • 앱의 전반적인 실행 흐름을 관리하는 역할
  • 앱이 시작되거나 종료될 때 필요한 설정을 수행
  • application(_:didFinishLaunchingWithOptions:)에서 앱 실행 시 초기 설정 진행

🔹 SceneDelegate

  • iOS 13부터 추가된 개념으로, 멀티 윈도우 환경을 지원하기 위해 도입됨
  • 앱의 UI가 생성되거나 사라질 때의 이벤트를 처리
  • sceneDidBecomeActive(_:), sceneWillResignActive(_:) 등을 활용하여 앱 상태 관리

정리

  • 앱의 전반적인 실행 흐름 → AppDelegate에서 관리
  • 개별적인 UI 씬(Scene) → SceneDelegate에서 관리

Xcode 디버깅 방법

코드를 작성하는 것만큼 중요한 것이 디버깅이다.
버그를 효과적으로 찾아내고 해결하기 위해 다양한 디버깅 방법을 배웠다.

🔹 print 문 사용

  • 가장 기본적인 디버깅 방법
  • print("디버깅할 값: \(value)") 형태로 콘솔에 출력
  • 간단한 값 확인에는 유용하지만, 많은 로그가 쌓이면 관리가 어려움

🔹 OSLog 사용

  • Apple에서 제공하는 로그 시스템
  • 로그 레벨을 설정하여 필요할 때만 특정 로그를 확인할 수 있음
  • 사용 예시
    import os
    let log = OSLog(subsystem: "com.myApp", category: "debug")
    os_log("디버깅 메시지: %@", log: log, type: .debug, "값 출력")

🔹 lldb 사용

  • Xcode의 강력한 디버깅 도구
  • 코드 실행 중 특정 지점에서 멈춘 후 변수 값을 확인하거나, 특정 코드 실행 가능
  • 자주 사용하는 lldb 명령어
    po 변수명  // 변수 값 출력
    p 변수명   // 변수 값 출력 (Swift 기본 형식)
    break set -n 함수명  // 특정 함수에서 중단점 설정

✍️ 배운점 & 느낀점

  • while문 안에서 switch 문을 사용할 때, break문의 적용 방식을 더 명확하게 이해하였다.
  • 앱 생명주기의 구조를 확장할 수 있어 앱 동작 방식에 대한 이해도를 높일 수 있었다.
  • AppDelegate와 SceneDelegate의 차이점을 확실히 정리할 수 있었다.
  • 디버깅 방법을 다양하게 적용해 보면서, 더 효과적인 문제 해결 방법을 고민해볼 수 있었다.
  • 객체지향 프로그래밍의 4가지 특징을 다시 복습하면서, 실무에서 어떻게 적용할지 고민해볼 수 있었다.

오늘도 모든 경험이 의미 있는 시간이었다!


0개의 댓글

관련 채용 정보