머리말


100문 100답 List
100문 100답 List 1~10
100문 100답 List 11~20
100문 100답 List 21~30
100문 100답 List 41~50
100문 100답 List 51~60
100문 100답 List 61~70
100문 100답 List 71~80
100문 100답 List 81~90
100문 100답 List 完

시작.

31. SwiftUI와 UIKit의 차이


SwiffUI

  • 개발 방식
    • 선언형 프로그래밍 방식으로 UI를 구성합니다.
    • 뷰의 구조와 모양을 선언하면, SwiftUI가 이를 자동으로 구현합니다.
  • 학습 난이도
    • UIKit에 비해 사용하기 쉽습니다.
    • 선언형 프로그래밍 방식은 코드가 더 간결하고 직관적이기 때문입니다.
  • 기능
    • UIKit에 비해 제한적이다.
  • 호환성
    • SwiftUI는 iOS13 이상에서만 사용할 수 있습니다.
  • 적합한 경우
    • 새로운 앱을 개발하는 경우
    • 간단하고 직관적인 UI를 원하는 경우
    • 빠르게 앱을 개발하고 싶은 경우

UIKit

  • 개발 방식
    • 명령형 프로그래밍 방식으로 UI를 구성합니다.
    • 뷰를 정의하고, 뷰의 속성과 동작을 설정하고, 뷰를 화면에 배치하는 등의 작업을 명렁어를 통해 수행합니다.
  • 학습 난이도
    • SwiftUI에 비해 사용하기 어렵습니다.
    • 명령형 프로그래밍 방식은 코드가 더 간결하고 복잡하기 때문입니다.
  • 기능
    • UIKit는 다양한 UI요소와 기능을 제공합니다.
  • 호환성
    • UIKit은 iOS 1.0부터 사용 가능합니다.
  • 적합한 경우
    • 기존 앱을 업데이트하는 경우
    • 복잡한 UI를 원하는 경우
    • 모든 iOS 버전을 지원해야 하는 경우

요약

항목 SwiftUI UIKit
개발 방식 선언형 프로그래밍 방식 명령형 프로그래밍 방식
학습 난이도 쉽다 어렵다
기능 제한적 다양하다
호환성 iOS 13 이상 iOS 1.0 이상
적합한 경우 새로운 앱, 간단한 UI, 빠른 개발 기존 앱, 복잡한 UI, 모든 iOS 버전 지원

32. Breakpoint와 Watchpoint의 차이에 대해 설명하세요.


Breakpoint

  • 역할
    • Breakpoint는 프로그램이 특정 코드 라인에 도달할 때 실행을 일시 중단시키는 데 사용됩니다.
    • 이는 코드의 실행을 멈추고 해당 지점에서 디버거에게 제어를 넘기는 데 도움이 됩니다.
  • 활용
    • 코드의 특정 지점에서 상태를 확인하거나 문제의 원인을 파악하기 위해 사용됩니다.
    • 조건부 중단점을 설정하여 특정 조건이 충족될 때만 중단되도록 할 수 있습니다.

Watchpoint

  • 역할
    • Watchpoint는 변수나 메모리 주소와 같은 특정 제이터가 변경될 때 실행을 일시 중단시키는 데 사용됩니다.
    • 이는 변수의 값이 어떻게 변하는지 추적하고 디버깅하는 데 도움이 됩니다.
  • 활용
    • 특정 변수의 값이 예상치 못한 변경을 일으켰을 때 디버깅하기 위해 사용됩니다.
    • 데이터 변화에 대한 추적 및 디버깅이 필요한 상황에서 유용하게 활용됩니다.

요약

특징 Breakpoint Watchpoint
역할 코드 라인에서 프로그램을 중단시킴 특정 데이터(변수 또는 메모리)가 변경될 때 프로그램 중단
활용 코드 실행 중 상태 확인, 특정 조건에서 중단 설정 데이터의 변경 추적 및 디버깅
  • Breakpoint는 코드 라인에 기반하여 특정 지점에서 프로그램을 중단시킵니다.
    Breakpoint는 코드의 흐름을 중단시켜 상태를 확인하거나 특정 조건에서만 중단되도록 설정됩니다.
  • Watchpoint는 데이터(변수 또는 메모리)에 기반하여 특정 데이터가 변경될 때 프로그램을 중단시킵니다.
    Watchpoint는 변수의 값이 변경될 때 중단시켜 데이터의 변화를 추적하고 디버깅하는 데 사용됩니다.

33. 앱의 크래시 원인을 찾는 방법에 대해 설명하세요.


Crash Logs 확인

  • 앱이 크래시하면 시스템은 로그를 생성합니다. Xcode의 Organizer에서 로그를 확인합니다.

Xcode의 디버깅 도구 사용

  • Breakpoint 설정, 디버그 콘솔을 통한 로그 출력 등을 활용하여 코드 실행 흐름을 파악합니다.

Instruments 사용

  • 메모리 누수나 크래시 발생 지점을 추적하기 위해 Instruments를 사용합니다.

예외 상황 처리

  • 예외 처리 코드를 작성하여 예외를 적절히 처리하고, 로그를 기록합니다.

프로파일링 도구 활용

  • Xcode의 Profiler 및 Instruments를 사용하여 성능, CPU, 메모리 사용량을 분석합니다.

오류 추적과 로깅

  • 코드에 로깅을 추가하여 실행 흐름을 파악하고, 잠재적인 크래시 지점에서 로그를 출력합니다.

디바이스 또는 시뮬레이터 변경

  • 크래시가 특정 디바이스에서만 발생하는 경우, 다른 환경에서 테스트합니다.

코드 리뷰 및 협업

  • 코드 리뷰를 통해 다른 개발자의 의견을 수렴하고, 팀 내 협업을 통해 문제를 해결합니다.

요약

앱 크래시 원인을 찾기 위해 로그 및 Xcode의 디버깅 도구를 확인하고, Instruments를 사용하여
성능 및 메모리 상태를 분석합니다.
예외 상황 처리 코드를 추가하고, 실행 중 로그를 통해 코드 흐름을 파악하여 디바이스나
시뮬레이터 변경과 코드 리뷰를 통해 팀 내 협업으로 원인을 찾습니다.

34. Instruments란 무엇인가요?

Instruments는 macOS에 포함된 디버깅 도구입니다.
앱의 성능, 메모리 사용량, 전력 사용량, 네트워크 사용량, 이벤트 흐름 등을 측정할 수 있습니다.

기능

  • CPU Profiler
    • 앱의 CPU 사용량을 측정합니다.
  • Memory Profiler
    • 앱의 메모리 사용량을 측정합니다.
  • Allocations Profiler
    • 앱의 메모리 할당을 추적합니다.
  • Energy Profiler
    • 앱의 전력 사용량을 측정합니다.
  • Network Profiler
    • 앱의 네트워크 사용량을 측정합니다.
  • Trace Profiler
    • 앱의 이벤트 흐름을 추적합니다.

35. 앱에서 메모리 누수를 방지하는 방법은 무엇인가요?


강한 참조 주의

  • 순환 참조를 피하기 위해 강한 참조를 최소화하고 weak 또는 unowned 참조를 사용합니다.

ARC(Automatic Reference Counting) 활용

  • ARC를 활용하여 수동으로 메모리를 해제하지 않아도 됩니다.

Delegate 및 Closure 주의

  • Delegate 패턴이나 Closure에서 순환 참조를 방지하기 위해
    [weak self] 또는 [unowned self]를 사용합니다.

메모리 누수 검사 도구 사용

  • Instruments나 Xcode의 메모리 그래프를 사용하여 메모리 누수를 식별합니다.

옵셔널 사용

  • 옵서널을 적절하게 사용하여 nil로 설정된 경우 메모리를 해제하고,
    불필요한 객체 참조를 방지합니다.

메모리 해제 전 확인

  • 객체를 해제하기 전에 해당 객체에 대한 참조를 모두 제거하는지 확인합니다.

Notification 및 Observer 관리

  • Notification을 사용할 때 적절한 시점에 옵저버를 등록하고 제거하여 불필요한 참조를 방지합니다.

코딩 스타일 및 규칙 준수

  • 일관된 코딩 스타일과 규칙을 유지하여 메모리 누수 가능성을 줄입니다.

36. 앱이 느릴 때 어떻게 해결하시겠어요?


1. 프로파일링 도구 사용

  • Instruments나 Xcode의 Profiler를 사용하여 앱의 성능 병목 현상을 식별하고 어떠 부분이 느린지 확인합니다.

2. 코드 최적화

  • 비효율적인 알고리즘 및 코드를 개선하고, 불필요한 반복문이나 계산을 줄입니다.

3. 비동기 작업 사용

  • UI스레드에서 수행되는 작업을 최소화하고,
    비동기적으로 백그라운드 스레드에서 작업을 처리하여 UI의 응답성을 향상시킵니다.

4. 이미지 및 미디어 최적화

  • 큰 이미지나 미디어 파일을 최적화하고,
    lazy loading을 통해 필요한 시점에만 리소스를 로드합니다.

5. 메모리 관리

  • 메모리 누수를 방지하고 메모리를 효율적으로 사용하기 위해
    Instruments를 사용하여 메모리 프로파일링을 수행하고 불필요한 객체 참조를 제거합니다.

6. Auto Layout 최적화

  • Auto Layout이 느린 경우, 불필요한 제약 조건을 최소화하거나,
    필요한 경우에만 업데이트하도록 설정합니다.

7. 네트워크 요청 최적화

  • 네트워크 통신이 느린 경우, 캐시를 효과적으로 사용하고,
    요청을 효율적으로 관리하여 대기 시간을 최소화합니다.

8. 컴파일러 최적화 활용

  • Swift 컴파일러의 최적화 옵션을 활용하여 더 효율적인 코드를 생성하도록 설정합니다.

9. 의존성 관리

  • 앱에 사용되는 라이브러리나 프레임워크의 버전을 최신으로 유지하고,
    필요없는 의존성을 정리합니다.

10. UI 향상

  • 뷰를 효율적으로 로드하고 표시하기 위해 필요한 만큼의 데이터만 사용하고,
    뷰의 재사용을 적극적으로 활용합니다.

11. 최적화된 알고리즘 사용

  • 알고리즘을 최적화하여 데이터 처리 및 연산에 소요되는 시간을 최소화합니다.

37. 서버와의 통신 중 발생할 수 있는 문제에 대비한 경험이 있나요?


이것은 예시입니다.

1. 네트워크 에러 핸들링

  • 네트워크 요청 중에 발생하는 에러에 대한 처리를 구현
  • HTTP 에러 코드를 확인하고 사용자에게 적잘한 메시지를 제공

    2. 타임아웃 및 연결 문제 처리

  • 서버와의 통신에서 타임아웃이나 연결 문제등에 대비하여 타임아웃 시간을 적절히 설정
  • 연결이 끊어졌을 때 재시도 매커니즘 구현

    3. 백엔드 변경에 유연한 구조

  • 서버 API 스펙이 변경될 수 있음에 대비하여, 유연한 구조를 유지
  • 모델과 네트워크 계층을 캡슐화하여 변경에 대응할 수 있도록 구현

    4. 오프라인 모드 지원

  • 네트워크 연결이 없는 상황에서도 어플케이션이 최소한의 기능을 지원할 수 있도록
    로컬 캐싱 및 데이터 저장소를 활용하여 오프라인 모드를 지원

    5. 프로그레시브 백오프 전략

  • 서버와의 연결 시 문제가 발생할 경우, 프로그레시브 백오프 전략을 도입하여
    재시도 간격을 점차 증가시켜 서버 부하를 최소화하고 안정적인 연결을 유지

    6. 로깅 및 애널리틱스

  • 앱에서 발생하는 네트워크 문제에 대한 로깅 및 애널리틱스를 통해
    문제의 근본적인 원인을 파악하고, 사용자 경험을 개선할 수 있도록 구현

    7. 보안 강화

  • 통신 중에 데이터가 노출되는 것을 방지하기 위해 SSL/TLS를 활용하고,
    민감한 정보를 안전하게 전송

    8. 테스트 환경에서 시나리오 시뮬레이션

  • 특정 네트워크 에러나 지연 시나리오를 시뮬레이션 하여 앱이 어떻게 반응하는지 테스트

요약

  1. 네트워크 에러 핸들링과 사용자에게 적절한 메시지 제공.
  2. 타임아웃과 연결 문제에 대한 타임아웃 설정 및 재시도 메커니즘 구현.
  3. 백엔드 변경에 대비한 유연한 코드 구조와 모델 네트워크 캡슐화.
  4. 오프라인 모드를 지원하는 로컬 캐싱 및 데이터 저장소 활용.
  5. 프로그레시브 백오프 전략 도입으로 안정적인 연결 유지.
  6. 로깅과 애널리틱스를 활용하여 문제 원인 파악 및 사용자 경험 개선.
  7. SSL/TLS를 활용한 데이터 보안 강화.
  8. 테스트 환경에서 다양한 시나리오 시뮬레이션을 통한 안정성 확인.

38. 앱에서 발생한 버그를 해결한 경험을 공유해주세요.

이것은 예시입니다.

한 앱에서 발생한 버그 중 하나는 사용자가 특정 화면에서 데이터를 입력하고 저장한 후,
다른 화면으로 이동할 때 발생한 문제였습니다.
이 버그는 다음과 같은 과정으로 해결되었습니다

1. 문제 파악 및 재현

  • 먼저 사용자의 보고를 기반으로 버그를 재현하고, 버그가 발생하는 정확한 시나리오를 파악
  • 화면 이동과 관련된 상황을 중점적으로 확인

2. 로그 및 디버깅

  • 해당 시나리오에서 발생하는 로그를 분석
  • 디버깅 도구를 사용하여 문제 발생 시 앱의 상태를 조사
  • 이를 통해 어떤 데이터가 손실되거나 화면 전환이 올바르게 이루어지지 않는지 확인

3. 코드 검토

  • 버그 발생 지점 주변의 코드를 검토하여 가능한 원인을 찾음
  • 데이터 저장 및 화면 이동과 관련된 부분을 중심으로 코드를 살펴봄

4. 테스트 케이스 작성

  • 버그를 재현하는 특정 테스트 케이스를 작성하여 버그 수정 후에도 문제가 재발하지 않도록 작성

5. 코드 수정 및 테스트

  • 발견된 문제를 수정
  • 수정된 코드에 대해 다양한 시나리오에서의 테스트를 진행
  • 유닛 테스트와 UI 테스트를 활용하여 안전성 검증

6. 릴리즈 및 모니터링

  • 수정된 코드를 포함한 새로운 빌드를 릴리즈
  • 사용자의 피드백 및 앱의 모니터링을 통해 추가 문제가 없는지 확인

7. 사용자 커뮤니케이션

  • 버그 수정 및 업데이트 내용을 사용자에게 공지
  • 해당 문제로 불편을 겪은 사용자들에게 감사의 말과 함께 문제가 해결되었음을 안내

이 경험을 통해 효과적인 버그 해결 과정과 사용자와의 원활한 소통의 중요성을 꺠달음

이것은 예시입니다!!!!!

39. RESTful API와 GraphQL의 차이에 대해 설명하세요.


RESTful API

  • 개념
    • RESTful API는 Representational State Transfer의 약자로,
      HTTP 프로토콜을 기반으로 하는 API 방식 입니다.

  • 특징
    • 리소스 기반
      • RESTful API는 리소스를 기반으로 하여 데이터를 전송합니다.
      • 리소스는 URI로 식별되며, GET, POST, PUT, DELETE 등의 HTTP메서드를 사용하여
        리소스와 상호 작용 할 수 있습니다.
    • 상태 정달
      • RESTful API는 상태 전달 방식을 사용합니다.
      • 서버는 클라이언트에게 리소스의 상태를 전달하고,
        클라이언트는 상태를 기반으로 하여 다음 작업을 수행합니다.
    • 계층 구조
      • RESTful API는 계층 구조를 사용하여 데이터를 전송합니다.
      • 리소스는 URI의 계층 구조에 따라 구성되며,
        클라이언트는 URI를 사용하여 필요한 데이터를 가져올 수 있습니다.

GraphQL

  • 개념
    • GraphQL은 Graph Query Language의 약자로, 데이터를 쿼리하기 위한 API 방식입니다.

  • 특징
    • 쿼리 기반
      • GraphQL은 쿼리 기반을 사용하여 데이터를 전송합니다.
      • 클라이언트는 서버에 쿼리를 보내고, 서버는 쿼리에 따라 데이터를 반환합니다.
    • 선언적
      • GraphQL은 선언적 방식을 사용합니다.
      • 클라이언트는 필요한 데이터를 선언적으로 쿼리하며,
        서버는 선언에 따라 데이터를 반환합니다.
    • 필수 데이터
      • GraphQL은 필수 데이터를 지정할 수 있습니다.
      • 클라이언트는 필수데이터를 지정하면, 서버는 반드시 해당 데이터를 반환해야 합니다.

요약

특징 RESTful API GraphQL
설계 방식 리소스 기반, 상태 전달, 계층 구조 쿼리 기반, 선언적, 필수 데이터
데이터 전송 방식 리소스 쿼리
데이터 전송 방식 HTTP 메서드 쿼리
데이터 구조 URI 계층 구조 선언적
장점 단순하고 이해하기 쉽다. 유연하고 효율적이다.
단점 데이터 전송 방식이 제한적이다. 데이터 구조가 복잡할 수 있다.

40. Codable 프로토콜의 역할은 무엇인가요?


Codable 프로토콜은 Swift의 데이터 모델을 직렬화 및 역직렬화하는 데 사용되는 프로토콜입니다.
직렬화는 데이터 모델을 다른 데이터 형식으로 변환하는 과정이고,
역직렬화는 다른 데이터 형식에서 데이터 모델을 복원하는 과정입니다.

Encoder / Decoder

  • Codable 프로토콜을 준수하는 데이터 모델은 다음과 같은 두 가지 메서드를 구현해야합니다.
    • encode(to: Encoder): 데이터 모델을 다른 데이터 형식에서 변환하는 메서드
    • init(from: Decoder ): 다른 데이터 형식에서 데이터 모델을 복원하는 메서드

Codable 사용처

  • 구조체
  • 클래스
  • 열거형

데이터 모델을 직렬화 하는 방법

struct User: Codable {
  let name: String
  let age: init
}

let user = User(name: "choi", age: 24)
let data = try encoder.encode(user)

// 위의 코드는 `User`구조체를 직렬화 하여 `Data`타입으로 변환합니다.

데이터 모델을 역직렬화 하는 방법

struct User: Codable {
  let name: String
  let age: init
}

let data = """
{
  "name": "choi"
  "age": 24
}
""".data(using: .utf8)!

let decoder = JSONDecoder()
let user = try decoder.decode(User.self, from: data)

// 위의 코드는 `Data`타입의 데이터를 `User`구조체로 역직렬화 합니다.

장점

  • 데이터 모델을 다른 데이터 형식으로 쉽게 변환할 수 있씁니다.
  • 데이터 모델을 저장하거나 전송하기 쉽습니다.
  • 데이터 모델을 쉽게 테스트할 수 있습니다.









다음에 계속


100문 100답 List에서 31~40번까지의 질문에 대한 답변입니다.
틀린 답변이 있거나 더 좋은 답변이 있다면 댓글 남겨주시면 적극 반영하겠습니다.
다들 화이팅 입니다.

100문 100답 List 1~10
100문 100답 List 11~20
100문 100답 List 21~30
100문 100답 List 41~50
100문 100답 List 51~60
100문 100답 List 61~70
100문 100답 List 71~80
100문 100답 List 81~90
100문 100답 List 完

이상.