---
# System prepended metadata

title: ' iOS interview 7 '
tags: ["\U0001F4BB 면접 질문"]

---

<h1><center> iOS interview 7 </center></h1>

###### tags: `💻 면접 질문`
###### date: `2025-10-1217:21:33.284Z`

> [iOS interview](https://github.com/JeaSungLEE/iOSInterviewquestions)

## 목표

말을 많이 연습하자!

- concurrency 마무리
- 면접 질문리스트 나머지


## Level2

### 안진

10. UIKit에서 테이블 뷰(UITableView)와 컬렉션 뷰(UICollectionView)의 차이점은 무엇인가요?
  - 테이블 뷰와 컬렉션 뷰에서 셀을 재사용하는 이유와 방법을 설명해주세요.
  - 테이블 뷰와 컬렉션 뷰의 데이터 소스(Data Source)와 델리게이트(Delegate)의 역할은 무엇인가요?
  - 컬렉션 뷰에서 사용할 수 있는 레이아웃(Layout)의 종류와 특징을 설명해주세요.

> UIKit 잘 모르는 사람이라.. 진짜 이 차이가 뭔지 궁금해서 가져왔어요

테이블 뷰는 단일 열 / 컬렉션 뷰는 복잡한 UI 활용 가능
-> 사실 컬렉션 뷰로 다 가능

단순한 리스트인 경우, 테이블 뷰가 더 좋음
테이블 뷰는 Swipable 적용 가능
컬렉션 뷰는 적용 불가능

FlowLayout / CompositionalLayout
- FlowLayout
  - 직접 계산 필요
  - 너무 오래됨
- CompositionalLayout
  - 비율로 Section, Group, Item 적용 가능
  - 이걸 더 많이 쓰거라



11. 레거시 MVC 프로젝트를 MVVM으로 점진적으로 마이그레이션하려면 어떤 전략을 사용하시겠습니까?
💡 힌트: 리스크를 최소화하면서 점진적으로 전환하는 방법을 생각하세요
  - 어떤 화면부터 마이그레이션을 시작하는 것이 좋을까요?
    - 복잡도가 높은 화면 vs 단순한 화면, 어떤 기준으로 선택하나요?
      > 복잡도가 높으면 더 뒤에 진행한다
      > 테스트를 더 많이 작성해봐야한다 / 사용성 테스트도 많이 해봐라

    - 테스트 커버리지가 높은 부분부터 시작하는 이유는?
      > 왜 테스트 커버리지를 고려해야 하지?
      
  - MVC와 MVVM이 공존하는 과도기에 발생할 수 있는 문제와 해결책은?
    - 데이터 흐름의 일관성을 유지하는 방법은?
    - 팀원들의 혼란을 최소화하는 방법은?
  - 아키텍처 변경의 성공 지표는 무엇으로 측정하나요?

> Presentation layer의 아키텍처 변경 시, 테스트 진행 방법이 어떻게 되는지?
> 마이그레이션 진행 시, 기존 활용 객체와 똑같다면 네이밍 차이를 어떻게 두는지?



14. 여러 개의 비슷한 네트워크 API 클라이언트를 프로토콜로 추상화하려면 어떻게 설계하시겠습니까?
  - 공통 기능을 프로토콜 확장으로 구현할 때의 이점과 주의점은?
    - 프로토콜 확장의 메서드 디스패치 방식과 override 불가능한 이유는? 
    - Associated Type을 사용한 제네릭 프로토콜의 장단점은?
  - 테스트를 위한 Mock 객체 생성이 쉬운 프로토콜 설계 방법은? <- 진짜 궁금한건 이거 💡
    > 안진 생각..
    > 의존성 주입이 가능한 형태로 설계해야 한다?
    > 필요한 다른 객체들에 대해서도 Mock으로 주입할 수 있어야 함..?
    - Dependency Injection과 프로토콜의 관계는?
  - SwiftUI의 View 프로토콜처럼 PAT(Protocol with Associated Type)를 활용하는 방법은?
  - 
TCA 쓰세요.. TestFeature 지원


### 태현

1. 테이블뷰를 빠르게 스크롤할 때 이미지가 잘못된 셀에 표시되는 문제를 어떻게 해결하나요?

- 셀 재사용 메커니즘

> Cell이 queue(큐)에서 다시 reuse(재사용)가 될 때 prepareForReuse()를 걸쳐서 초기화를 한 후 다시 cellForeRowAt를 통해 Cell이 표시가 됩니다.

- 셀 재사용(Cell Reuse) 메커니즘이 이 문제와 어떤 관련이 있나요?

> SwiftUI에서 기본 VStack/HStack에서는 재사용 고려 X..
> List나 LazyVStack, LazyHStack 같은 친구들은 내부적으로 알아서 재사용해줍니다요 네넹

~~5. viewDidLoad에서 네트워크 요청을 하면 어떤 문제가 발생할 수 있나요?~~

8. iOS 앱에서 의존성 주입(Dependency Injection)은 어떤 목적으로 사용되나요?

- 추상화 
- 확장성

- 많이들 이야기하는 DI 가 가지는 장점이나 목적으로는, 테스트 용이 / 유지보수 용이 / 결합 낮추기 등?
- 근데 진짜 써보고 느낀 가장 큰 장점은
- 내부 구현 없이 활용이 가능해져서 구현 속도나 편의가 좋다?


17. Swift의 고급 제네릭 기능과 타입 소거(Type Erasure)에 대해 설명해주세요.

- AnyPublisher

18. iOS 앱에서 Deep Link와 Universal Link의 차이점은 무엇인가요?


applinks:app.com

### 태윤

8. iOS 앱에서 의존성 주입(Dependency Injection)은 어떤 목적으로 사용되나요?
- 의존성 주입의 세 가지 유형(Initializer Injection, Property Injection, Method Injection)을 설명해주세요.
 init(), 


```swift
let vc = UserViewController()
vc.viewModel = UserViewModel(client: RealAPIClient())
```
> Property Injection

```swift
final class UserService {
    func fetchUser(using client: APIClient) async throws -> User {   // ✅ 메서드 주입
        try await client.request(.getUser)
    }
}
```
> Method Injection

- 의존성 주입 컨테이너(Dependency Injection Container)란 무엇인가요?
팩토리 같은 놈

14. 여러 개의 비슷한 네트워크 API 클라이언트를 프로토콜로 추상화하려면 어떻게 설계하시겠습니까?
- 공통 기능을 프로토콜 확장으로 구현할 때의 주의점은?
    관리할 곳이 많아진다.
    Pure한 곳에서만 쓰기
- 프로토콜 확장의 메서드 디스패치 방식과 override 불가능한 이유는?
    override - 구현체가 아니므로 불가능함
```
    구분	정의 위치	디스패치 방식	설명
① 프로토콜 요구사항	protocol 본문	동적 디스패치	실제 타입이 어떤 구현을 가지고 있는지 런타임에 결정
② 프로토콜 확장 메서드 extension 내부 (요구사항 아님) 정적 디스패치 컴파일 타임에 결정 (오버라이드 불가)
```
- Associated Type을 사용한 제네릭 프로토콜의 장단점은?

```swift 
protocol DataSource {
    associatedtype Item
    func item(at index: Int) -> Item
}

struct IntSource: DataSource { func item(at index: Int) -> Int { 1 } }
struct StringSource: DataSource { func item(at index: Int) -> String { "A" } }

let sources: [Any] = [IntSource(), StringSource()]

for source in sources {
    if let intSource = source as? IntSource {
        print(type(of: intSource.item(at: 0)))  // Int (런타임에 확인)
    } else if let strSource = source as? StringSource {
        print(type(of: strSource.item(at: 0)))  // String
    }
}

```

> 런타임에만 알 수 있는 상황


20. Swift에서 키 경로(Key Path)란 무엇이며, 어떻게 사용하나요?
> (\.model)

- 런타임에 키 경로를 사용하여 속성에 접근하는 방법은 무엇인가요?

인스턴스에서 직접 접근하는 방식으로 진행하면, 속성 이름이 코드에 하드코딩된다.
그리고 접근할 속성이 컴파일 타임에 고정된다.

Key Path로 접근한다면?
접근할 속성을 런타임에 동적으로 변경할 수 있다.

(사실 이 말이 너무 와닿지 않지만.. 아래와 같은 예시를 들 수 있을 듯)

```swift
func getValue<T>(from book: Book, keyPath: KeyPath<Person, T>) -> T {
    return book[keyPath: keyPath]
}

let title = getValue(from: book, keyPath: \Book.title)  // "안녕"
let price = getValue(from: book, keyPath: \Book.price)    // 10000

struct User {
    var name: String
    var age: Int
}

var user = User(name: "TaeYoon", age: 26)

let writablePaths: [String: WritableKeyPath<User, Any>] = [
    "name": \User.name as! WritableKeyPath<User, Any>,
    "age": \User.age as! WritableKeyPath<User, Any>
]

// ⚠️ 주의: 타입 캐스팅이 필요 (KeyPath는 제네릭 타입 안전 구조)
if let keyPath = writablePaths["age"] {
    user[keyPath: keyPath] = 27
}

print(user.age) // 27



```
> 실제 값 할당 및 가져오는건 런타임

- 키 경로와 KVO(Key-Value Observing)의 관계를 설명해주세요.


```swift
import Foundation

class Person: NSObject {
    @objc dynamic var name: String
    
    init(name: String) {
        self.name = name
    }
}

class ViewController: UIViewController {
    var person: Person!
    var observation: NSKeyValueObservation?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        person = Person(name: "Alice")
        // ⬇️ 여기 이렇게 KeyPath로 접근한다
        observation = person.observe(\.name, options: [.new]) { (person, change) in
            if let newName = change.newValue {
                print("Name changed to: \(newName)")
            }
        }
    }
    
    deinit {
        observation?.invalidate()
    }
}

```

https://ahyeonlog.tistory.com/38