---
# System prepended metadata

title: '모의면접(메리,맥스,경민)'

---

📌 경민 질문 답변
---

## 1. 오토레이아웃은 bounds를 다루는 걸까요? frame을 다루는 걸까요?
- 오토레이아웃을 통한 제약을 기준으로 frame의 좌표와 크기를 결정함
### iOS 화면 체계에서 bounds 와 frame의 차이를 설명해주세요
- frame은 슈퍼 뷰 좌표계 기준으로 자신의 위치와 크기를 나타내고 bounds는 자신의 좌표계 기준으로 자신의 위치와 크기를 나타낸다.
### bounds를 활용해본 경험이 있나요? bounds는 언제 활용해볼 수 있을까요?
- frame으로 뷰의 위치를 잡아야하는 경우 슈퍼뷰의 bounds를 기준으로 잡을 수 있다.


### 오토레이아웃과 frame의 차이에 대해 설명해주세요
- frame은 슈퍼 뷰의 좌표계에서 뷰의 원점, 높이, 너비를 정의한다. UI 배치를 위해 뷰 계층 구조의 모든 뷰에 대한 크기와 위치를 계산해야 한다. 화면 회전 등의 변경 사항이 생기면 영향을 받는 모든 뷰에 대해 프레임을 다시 계산해야 한다. 하지만 직접 위치를 잡기 때문에 성능은 좋다.
- 오토레이아웃은 constraint를 통해 각 뷰의 크기와 위치를 계산한다. 이는 내부 및 외부 변경 사항 모두에 동적으로 대응하는 레이아웃을 생성한다. constraint는 두 뷰 간의 관계를 나타낸다.

### Intrinsic content size에 대해 설명해주세요
- 뷰의 현재 컨텐츠를 기반으로 크기가 정해진다. 레이블, 버튼 등은 표시되는 텍스트 양과 글꼴에 따라 결정되고 이미지 뷰는 이미지의 크기로 결정된다.

### CHCR에 대해 설명해주세요
- content hugging priority는 뷰가 늘어나지 않기 위한 우선 순위
- compression resistance priority는 뷰가 줄어들지 않기 위한 우선 순위

### Superview와 Safe Area에 제약을 줄 때 각각의 차이점을 설명해주세요
- Safe Area에 제약을 줄 때는 뷰가 디바이스의 안전한 표시 영역 내에서 레이아웃됨
- 뷰의 상위 컨테이너로서 Superview에 제약을 줄 때는 해당 뷰가 Safe Area를 고려하지 않고 전체 Superview에 대한 레이아웃을 설정함

## 2. Convenience init에 대해 설명해주세요
- 클래스를 위한 이니셜라이저. 일부 파라미터에 기본 값을 사용하여 designated 이니셜라이저를 호출한다. 특정 유즈케이스나 인풋값을 위해 만들 수도 있다. 공통 초기화 패턴에 대한 시간을 절약하거나 클래스 초기화 의도를 더 명확하게 만들 때 사용한다.
### Convenience init은 구조체에서 사용할 수 있나요?
- convenience init은 클래스를 위한 이니셜라이저이기 때문에 값 타입에서 사용할 수 없다.
### 왜 구조체에서 사용할 수 없나요?
- convenience init은 클래스를 위한 이니셜라이저이기 때문에 값 타입에서 사용할 수 없다. 구조체는 이니셜라이저를 designated와 convenience로 나누지 않는다.
### Convenience init이 필요한 이유가 무엇인가요?
- 공통 초기화 패턴에 대한 시간을 절약하거나 클래스 초기화 의도를 더 명확하게 만들 때 사용한다.


### Memberwise init에 대해 설명해주세요
- struct는 사용자 정의 이니셜라이저를 정의하지 않은 경우 자동으로 모든 프로퍼티를 초기화할 수 있는 이니셜라이저를 받는다.

### default init에 대해 설명해주세요
- class든 struct든 모든 프로퍼티에 기본값이 있고 이니셜라이저가 정의되어 있지 않은 경우 디폴트 이니셜라이저를 제공한다(init())

### 이니셜라이저 delegation rule(위임 호출) 3가지에 대해 설명해주세요
- 1. designated 이니셜라이저는 슈퍼 클래스의 designated 이니셜라이저를 호출해야 한다. 
- 2. convenience 이니셜라이저는 같은 클래스 내의 다른 이니셜라이저를 호출해야 한다. 
- 3. convenience 이니셜라이저는 궁극적으로 designated 이니셜라이저를 호출해야 한다.

### Failable Initializer(옵셔널 이니셜라이저)에 대해 설명해주세요
- 이니셜라이저가 초기화를 실패할 수 있는 경우에 사용됩니다. 초기화에 실패하면 nil을 반환하며, 성공하면 옵셔널 값이나 일반 객체를 반환합니다. 이를 통해 초기화 과정에서 오류가 발생할 수 있는 상황에서 안전하게 처리할 수 있습니다.


--- 
📌 맥스 질문 답변
---

![](https://hackmd.io/_uploads/r1hxQz3-6.png)

## iOS 앱의 상태 변화에 따라 호출되는 메서드 종류에 대해 설명해주세요.


### 앱 실행 상태 변화시 호출되는 UIApplicationDelegate 메서드

|~iOS 12|iOS 13 ~|
|:-:|:-:|
|<img src="https://docs-assets.developer.apple.com/published/64a2e0dab8/app-state@2x.png" width="400">|<img src="https://docs-assets.developer.apple.com/published/c834d5ac04/scene-state@2x.png" width="400">|


#### 앱 초기화 관련 활용 메서드
(참고 링크: [UIApplicationDelegate](https://developer.apple.com/documentation/uikit/uiapplicationdelegate))
- `application(_: willFinishLaunchingWithOptions:)`
    - 앱이 구동되어 필요한 초기 실행 과정이 완료되기 직전 호출되는 메서드
    - 앱을 초기화하고 실행할 준비를 하는 데 필요한 처리

- `application(_: didFinishLaunchingWithOptions:)`
    - 앱이 사용자에게 화면으로 표시되기 직전에 호출되는 메서드
    - 앱이 실행된 후 진행할 커스터마이징 또는 초기화 코드 작성
    - *iOS 12까지는 이 메서드를 통해 UIWindow 개체를 구성하고 ViewController 인스턴스를 할당했었음 -> SceneDelegate로 이동됨*

#### 앱 생명주기 관련 이벤트 메서드
- `applicationDidBecomeActive(_:)`
    - 실행된 앱이 전면(Foreground)에 표시될 때 호출되는 메서드
    - 앱이 Inactive 상태에 들어가면서 일이 중지된 작업이 있다면 재시작하는 코드를 여기에 작성해야 함(예: 타이머나 스톱워치는 Inactive 상태에서는 화면 갱신이 이루어지지 않음)

- `applicationWillResignActive(_:)`
    - 앱이 백그라운드로 이동 중에 호출되는 메서드
    - 일시정지, 타이머 비활성화 등의 코드 작성

- `applicationWillEnterForeground(_:)`
    - 앱이 전면(Foreground)으로 올라올 때 호출되는 메서드
    - API를 통한 앱 상태 갱신시 사용

- `applicationDidEnterBackground(_:)`
    - 앱이 백그라운드 상태에 진입했을 때 호출되는 메서드
    - 즉 미래 어느 순간에 앱이 종료된다는 의미 -> 공유 자원 해제 처리 & 사용자 데이터 및 다시 실행될 때 현재 상태를 복구할 수 있도록 필요한 상태 정보 저장 처리

- `applicationWillTerminate(_:)`
    - 앱이 종료되기 직전에 호출되는 메서드
    - 사용자 데이터 등을 종료 전에 한 번 더 저장

<br><details>
<summary>기타 환경 변화에 따른 이벤트 메서드</summary>
<div markdown="1">

#### 환경이 바뀔 때 실행되는 메서드
- `applicationProtectedDataDidBecomeAvailable(_:)`
    - 보호된 파일이 사용할 수 있게 되었음을 알림

- `applicationProtectedDataWillBecomeUnavailable(_:)`
    - 보호된 파일이 사용할 수 없어질 예정임을 알림

- `applicationDidReceiveMemoryWarning(_:)`
    - 앱이 시스템 메모리 경고를 받았음을 알림

- `applicationSignificantTimeChange(_:)`
    - 시간에 큰 변화가 생겼음을 알림

#### Background에서 데이터를 다운로드할 때
- `application(_:, handleEventsForBackgroundURLSession:, completionHandler:)`
    - URL 세션과 관련된 이벤트가 처리되기를 기다리고 있다고 알림

...

</div>
</details>
<br>


### 앱 실행 상태 변화시 호출되는 UISceneDelegate 메서드

#### Scene 연결 및 연결 해제
- `scene(_:willConnectTo:options:)`
    - 새로운 UI 인스턴스가 생성되거나 복원될 때 호출됨
    - 이 메서드에서 해당 Scene과 관련된 UI 구성, 초기화 작업을 수행

- `sceneDidDisconnect(_:)`
    - Scene이 메모리에서 제거되기 전 호출됨
    - Scene이 더 이상 사용되지 않을 때 정리 작업을 수행

#### Foreground로 전환 중
- `sceneWillEnterForeground(_:)`
    - Scene이 Foreground로 이동하기 전에 호출됨
    - 앱 상태를 갱신하거나 데이터를 업데이트하는 작업에 사용
    - 메서드 뒤에 항상 `sceneDidBecomeActive(_:)`를 호출

- `sceneDidBecomeActive(_:)`
    - Scene이 활성화되어 사용자에게 보이기 전에 호출됨
    - View 내용을 새로 고치거나, 타이머를 시작하거나, UI의 프레임 속도를 높일 수 있음

#### Background로 전환 중
- `sceneWillResignActive(_:)`
    - Scene이 비활성화되어 백그라운드로 이동하기 직전 호출됨
    - 사용자와의 상호작용을 중지하도록 준비
    - 일시 중지, 타이머 비활성화 등을 수행하는 코드 작성
    - Scene에 저장되지 않은 데이터가 있는 경우 해당 데이터가 손실되지 않도록 저장하는 방법 중 하나

- `sceneDidEnterBackground(_:)`
    - Scene이 백그라운드로 이동할 때 호출됨
    - Scene의 메모리 사용량을 줄이고 공유 리소스를 확보함
    - 메서드 반환 후 App Swicher에 표시하기 위해 Scene 인터페이스 스냅샷을 찍음
    - 스냅샷에 민감한 사용자 정보가 포함되어있지 않은지 확인 필요

<br><details>
<summary>기타 환경 변화에 따른 이벤트 메서드</summary>
<div markdown="1">
    
#### URL을 여는 중
- `scene(_:openURLContexts:)`
    - Scene API를 통해 URL을 열도록 요청하는 메서드로 여러 뷰 컨트롤러를 관리하는 데 사용됨. 
    - 앱이 URL을 열 때 호출되고 주로 앱 내에서 다른 컨텐츠로 이동하거나 외부 앱과 상호작용할 때 사용됨.

#### 지속적인 사용자 활동
- `scene(_:willContinueUserActivityWithType:)`
    - 지정된 유형의 활동 처리를 준비하기 위해 호출
    - 메서드 반환 후 Scene이 활동을 처리하고 있다는 피드백을 사용자에게 제공함

- `scene(_:continue:)`
    - 제공된 활동 객체의 데이터로 지정된 Scene을 업데이트하기 위해 호출
    - 다른 기기에서 발생할 수 있는 활동 객체에 대한 모든 데이터를 수신한 후에만 앱의 메인 스레드에서 이 메서드를 호출

- `scene(_:didFailToContinueUserActivityWithType:error:)`
    - 지정된 활동을 완료할 수 없음을 사용자에게 알리기 위해 호출
    - 이 메서드를 구현하지 않으면 UIKit은 실패 이유에 대한 적절한 메시지와 함께 사용자에게 오류를 표시함

#### Scene의 상태 저장
- `stateRestorationActivity(for:)`
    - Scene의 현재 상태에 대한 정보가 포함된 NSUserActivity 개체를 반환하기 위해 호출
    - Scene의 연결을 끊었다가 다시 연결한 후 해당 상태를 다시 복원할 수 있도록 충분한 정보를 저장해야 함

- `scene(_:restoreInteractionStateWith:)`
    
- `scene(_:didUpdate:)`
     - 지정된 사용자 활동 개체에 최종 데이터를 추가하기위해 호출
    
</div>
</details>
<br>

## App Delegate와 Scene Delegate의 역할 차이는 무엇인가요?
- App Delegate
    - App 자체의(Process) Life Cycle 및 설정 관리
    - 앱의 시작/종료 포함 애플리케이션 수준의 이벤트 처리
    - 푸시 알림 등록, 위치 서비스 등의 외부 서비스 처리 가능
    - Session의 Life Cycle 관리
        - Scene Session을 통해 Scene에 대한 정보를 받아서 해당 사이클을 관리함
        - application(_ : configurationForConnecting: options:) -> UISceneConfiguration
            - 새 씬이나 윈도우가 필요할 때마다 호출됨
            - 앱 시작시 호출되지 않고 새 씬이나 창을 가져야 하는 경우에만 호출됨
        - application(_ : didDiscardSceneSessions:)
            - 씬을 삭제할 때(예: 멀티 태스킹 창에서 스와이프) 또는 프로그래밍 방식으로 엡 제거시 호출
- Scene Delegate
    - 화면에 표시될 내용(Scene/Window)을 관리
    - UI Life Cycle 관리
    - Entered Foreground, Became Active 상태 등은 Scene Delegate에서 관리
    - UISceneSession의 Scene 생성, 파괴 및 상태 복원과 같은 Scene의 생명주기 이벤트 처리
    - 하나의 앱은 여러개의 Scene과 SceneDelegate 객체를 동시에 활성화시킬 수 있음
### 꼬리 질문: UISceneDelegate는 직접 객체를 생성하면 안되는데 왜 그럴까요?
- SceneSession 및 Scene Configuration의 관리 시스템 기반으로 UIKit이 자동으로 UISceneDelegate 객체를 관리하도록 설계되었기 때문에 직접 UISceneDelegate 객체를 생성하면 이러한 시스템 관리 및 복잡성을 증가시킬 수 있으며, 예기치 않은 동작을 초래할 수 있다.
    
#### 2. UI 객체들의 계층 구조와 각 역할에 대해 설명해주세요.
|~iOS 12|iOS 13 ~|
|:-:|:-:|
|<img src="https://hackmd.io/_uploads/B1UVtBpWT.png" width="1000">|<img src="https://hackmd.io/_uploads/r1uEYSTWa.png" width="1000">|
- `UIView`
    - 화면에 컨텐츠를 그리고 사용자와 직접 상호작용하여 처리하는 객체
    - UI의 기본 클래스로 다른 뷰 또는 컨트롤 요소 계층
- `UIWindow`
    - UIView의 서브 클래스로 앱의 UI에 대한 배경과 이벤트를 뷰에 전달하는 객체
    - iOS 13 이전까지는 하나의 앱에서는 하나의 Window를 가졌지만 이후부터는 아이패드 지원으로 인해 AppDelegate와 SceneDelegate의 분리로 여러 개의 Window를 가질 수 있게 되었음
- `UIWindowScene`
    - UIScene의 서브 클래스로 1개 또는 그 이상의 Window를 관리하는 객체
    - window와 scene 두 가지의 프로퍼티를 갖음
    - 해당 객체는 직접 생성을 권유하지 않음. 따라서 info.plist에서 configuration time에 UIWindowScene 객체를 사용할 클래스의 이름을 지정하여 사용하는 것을 권장
- `UIScreen`
    - 하드웨어 기반 디스플레이와 관련된 속성을 정의하는 객체
    - 하나 이상의 연결된 디스플레이에 대한 속성과 메서드를 제공하여 화면 크기, 해상도, 화면 방향 같은 관련 정보를 설정하는 데 사용됨


## GCD와 Operation의 차이에 대해 설명해주세요.

#### DispatchQueue
- Serial / Concurrent로 나뉘어 순차적, 병렬적 처리가 모두 가능하지만 늘 FIFO 방식으로 실행된다
    - **꼬리질문: DispatchQueue에는 우선순위 처리방식이 없을까요?**
        - 동시 처리일 경우 QoS 파라미터를 사용해서 우선순위 지정 가능
            - userInteractive, userInitiated, default, utility, background 
                - 왼쪽으로 갈수록 빨리 처리되고, userInteractive는 유저와 상호작용도 가능. 기본값은 default
                - UI 관련일 경우 userInteractive로 사용하는 것이 좋다
                - 길게 지속되는 작업은 utility, 사용자에게 직접적으로 인지되지 않아도 되는 부분은 background 권장
            - 우선순위가 높은 작업은 더 많은 thread에 배치된다
            - (비고: 큐 자체에도 우선순위를 줄 수 있고, 작업을 대기열에 보내는 방식에도 QoS 값을 줄 수 있다. 이때 큐와 작업의 우선순위가 각자 다르다면 해당 작업이 끝날 때까지 둘 중 더 높은 쪽으로 자동 조절된다.)
- sync는 스레드를 재사용, async는 새로 생성 -> async 사용시 무한으로 늘어날 수 있음
- 기본적으로 멀티스레딩 방식이기 때문에 Thread Explosion을 야기할 수 있음
#### OperationQueue
- Operation 객체들을 priority에 의해서 실행시키는 queue
- 디스패치 큐의 코코아 대체제. NSOperationQueue 클래스 기반
- 오퍼레이션 큐는 언제나 동시적으로 진행되긴 하지만 순차적인 실행이 필요할 경우 디펜던시를 활용할 수 있다 -> FIFO가 아닌 우선순위 기반 처리를 진행함(우선순의 팩터를 전달받음)
- 오퍼레이션 큐에 넣는 태스크는 반드시 NSOperation 클래스 인스턴스여야 함
- 오퍼레이션 객체들은 KVO 알림을 생성해준다
- 일시중지, 다시시작, 취소 가능(취소 작업시 동작은 하단 참조). 기능은 많이 제공해주지만 때문에 더 무겁기도 함
- 동시 실행 가능한 연산의 최대수 지정 가능
    - **꼬리질문: DispatchQueue를 활용하여 이 부분을 비슷하게 구현할 수는 없을까요?**
        - DispatchSemaphore 활용할 수 있음

### 어떤 경우에 각각의 기술을 선택할지 자신의 선택 기준에 대해 알려주세요.
### 각각의 기술을 사용할 때 작업을 취소하면 곧바로 취소가 되나요?
- **GCD**: 작업을 취소하거나 중단하는 과정이 복잡하며 직접 처리해야 함. 이때 이미 시작된 작업은 취소되지 않음.
- **Operation**: Operation, OperationQueue는 작업을 취소하거나 중단하는 메커니즘을 제공하기 때문에 작업취소할 때 더 용이함. 이미 시작된 작업이 취소되었을 경우 해당 작업을 중지하고 완료된 것으로 표시함.
#### 작업을 취소할 때 벌어지는 일에 대해서 설명해주세요.
- **DispatchQueue**
    - 취소 후에는 작업 항목을 실행하려는 시도가 모두 반환됨. 이미 시작된 작업 항목의 실행에는 영향을 미치지 않음.
    - 관련 자원의 해제는 블록 객체의 실행이 다음에 시도될 때까지(또는 이미 진행 중인 실행이 완료될 때까지) 지연됨.
- **OperationQueue**
    - 작업 객체를 취소해도 객체는 대기열에서 사라지지 않음. 하지만 가능한 한 빨리 작업을 중지해야 한다고 객체에 알림.
    - 현재 실행 중인 작업의 경우, 작업 객체의 작업 코드가 취소 상태를 확인하고, 하고 있는 일을 중지하고, 완료된 것으로 표시함.
    - 대기열에 있지만 아직 실행되지 않은 작업의 경우, 대기열은 여전히 작업 객체의 start() 메서드를 호출하여 취소 이벤트를 처리하고 완료된 것으로 표시함.





---
📌 메리 질문 답변
---

## 1. Singleton 디자인 패턴을 활용하는 경우를 예를 들어 설명해주세요

`Singleton` 디자인 패턴은 어떤 클래스가 단 하나의 인스턴스만을 갖도록 보장하는 패턴
`Singleton`은 전역 상태를 유지하거나, 공통된 리소스에 접근할 때 유용함

### 1-1 **Singleton 패턴을 활용하는 경우**
유일한 인스턴스 생성을 보장하고 전역에서 액세스가 필요한 경우 사용할 수 있음

```swift
final class NumberFormatManager {
    
    // MARK: - Static Property
    static let shared = NumberFormatManager()
    
    // MARK: - Private Property
    private let formatter = NumberFormatter()
    
    // MARK: - Life Cycle
    private init() { }
    
    // MARK: - Function
    // ...
}
```
- `NumberFormatter`와 같이 인스턴스를 생성하는 작업이 큰 작업에 해당하는 경우 하나의 매니저를 `Singleton` 패턴으로 만들어 전역에서 접근하도록 할 수 있음

### 1-1-꼬리질문 **Swift에서의 Singleton 사용**

```swift
UIScreen.main
UserDefaults.standard
UIApplication.shared
FileManager.default
NotificationCenter.default
```

### 1-2 **Singleton 디자인 패턴의 장단점을 설명해주세요**

**장점**
- 유일한 인스턴스
- 자원 관리가 쉬움
- 전역 액세스가 가능

**단점**
- 전역 액세스가 가능
- 변경점을 찾기가 어려움
- `static`하기 때문에 데이터 영역에 메모리가 잡혀있음
- `SRP`, `DIP`, `OCP` 위배

### 1-2-꼬리질문 `SRP`, `DIP`, `OCP`를(또는 이중 1개) 어떻게 위배하는지 설명해주세요

## 2. Core Graphics에 대해 설명해주세요

`Core Graphics`은 iOS 및 macOS 애플리케이션에서 2D 그래픽을 그리고 조작하는 데 사용되는 프레임워크

### 2-1 **Core Graphics의 context에 대해 설명해주세요**

**CGContext**
> A Quartz 2D drawing environment.

`context`는 그리기 작업을 수행하는 환경이며, 그래픽 스트림을 생성하고 출력하는 데 사용되고 화면에 그림을 그리거나 PDF 파일로 저장하는 등의 작업을 수행

<br>

## 3. View Contoller의 View의 상태변화에 따른 메서드의 호출순서를 이야기해보세요

**View 상태 메서드**
1. loadView(): 뷰 컨트롤러가 뷰를 로드할 때 호출
2. viewDidLoad(): 뷰가 로드된 후에 호출
3. viewWillAppear(_:): 뷰가 화면에 나타나기 직전에 호출
4. viewIsAppearing(_:): 뷰컨트롤러에게 뷰를 뷰 계층에 추가하고 있음을 알림
5. viewDidAppear(_:): 뷰가 화면에 나타난 후에 호출
6. viewWillDisappear(_:): 뷰가 화면에서 사라지기 직전에 호출
7. viewDidDisappear(_:): 뷰가 화면에서 사라진 후에 호출

**View 레이아웃 메서드**
1. viewWillLayoutSubviews(): 뷰의 하위 뷰가 레이아웃을 업데이트하기 직전에 호출
2. viewDidLayoutSubviews(): 뷰의 하위 뷰가 레이아웃을 업데이트한 후 호출

![](https://hackmd.io/_uploads/ryULSB6ba.png)

### 3-1 **viewWillAppear와 viewDidAppear에서 무엇을 하면 좋을까요?**

**viewWillAppear**
뷰 컨트롤러가 화면에 나타날 때 필요한 작업

**viewDidAppear**
뷰 컨트롤러가 화면에 나타난 직후에 실행해야 하는 작업

### 3-2 **UIView의 layoutSubviews 메서드는 viewWillAppear보다 먼저 호출되나요? 그렇게 생각한 이유는 무엇인가요?**

`viewWillAppear`가 먼저 호출됨
뷰가 로드된 후 뷰가 나타나기 직전에 레이아웃이 설정되기 때문에 `layoutSubviews`는 `viewWillAppear` 보다 늦게 그리고 `viewDidAppear` 보다 빨리 호출됨

<br>

## 4. 스위프트 언어의 String에서 subscript를 통해 문자에 접근할 수 없는 이유에 대해 설명해주세요.

`Swift`에서 `Character`는 1개 이상의 `Unicode Scalar`로 이루어져 있어 크기가 가변적이기 때문에 `subscript`를 통해 문자에 접근할 수 없고 `String.index`로 접근해야함

<br>

## 5. Custom View를 구현하려면 어떻게 해야하는지 설명해주세요

1. `UIView`를 상속 받는 `Custom View` 객체 생성
2. 코드를 이용한 `UI` 구현
3. 이벤트 동작 및 핸들링 함수 추가

### 5-1 **인터페이스빌더로 UI짜는거랑, 코드로만 UI를 짜는거랑 장단점**

|장단점|스토리보드|코드베이스|
|---|---|---|
|장점|- 눈으로쉽게보면서레이아웃작업가능<br>- 뷰 컨트롤러에 추가적인 코드작업 필요없음<br>- 레이아웃 에러찾기 쉬움|- 어떤 일이 일어나는 지 알 수 있음<br>- 개발자 마음대로 제어가 가능<br>- 충돌 시 해결 쉬움<br>- 재사용성|
|단점|- 충돌시 골치아픔 <br>- 코드로 작성한 UI에 비해 오버 헤드가 큼| - 개발기간이 XIB에 비해 큼 <br>- 에러찾기 어려움 <br>- 오래된 코드일 경우 리팩토링 어려움|

그외 장단점
1. 스토리보드
(1) 장점
- 구현하기 쉽다. 
- 프로토타입을 빠르게 만들 수 있다.
- 화면 전환(실행흐름)을 쉽게 파악할 수 있다.
- Static Cell을 이용할 수 있다. (스토리보드에서만 가능한 기능)
(2) 단점
- 여러 사람이 함께 작업하는 경우, Merge 충돌이 일어날 수 있다.
- 재사용 시, 뷰 컨트롤러 자체를 함께 복사해야 하기 때문에 재사용성이 낮다.
- 스토리보드는 의존하는 모든 뷰 컨트롤러들과 함께 이동되어야함
- 스토리보드는 뷰 컨트롤러 사이의 실행 흐름을 다루지만, 데이터의 흐름은 관여하지 않는다. 

2. Code
(1) 장점
- 하나하나 코드로 구현되어 있기 때문에 기능의 정의가 직관적이다. 
- 읽기 쉽고, 유지보수가 간편하다.
- 스토리보드와 xib로도 할 수 있는 것과 두 기능으로는 할 수 없는 것 모두 코드로는 구현할 수 있다.
- UI를 코드로 작성하면 더 많은 제어와 이해를 할 수 있고, 다양하게 구현할 수 있다.
- 코드만이 유일한 방법인 경우가 있다. 예를 들어 뷰가 이리저리 움직이는 다이나믹 레이아웃이나, 내용물에 기반을 두고 변화하는 레이아웃 등이 있다.
- 분명한 문법적 의미를 갖고 있기 때문에 충돌을 해결하는 것이 그리 어렵지 않다. 
- 성능 관점에서 스토리보드와 Xib는 로드와 파싱에 대한 오버헤드를 거치고 최종에서야 간접적으로 코드로 변환되는 반면에, 코드로 만들면 이런 과정이 필요 없다.
(2) 단점
- 다른 사람이 개발했던 코드를 리팩토링하기 복잡하다. 
- 레이아웃이 화면에 어덯게 보여지고 작동하는지 보여주기 위해 작업해야하는 시간이 xib, 스토리보드에 비해 오래 걸린다.
<br>