잡다한 팁

iOS 면접자료 정리

# Array와 linked List

  • Array는 Random Access를 지원 시간 복잡도 O(1), index를 통해 직접적 접근가능
  • element들은 인접한 memory위치에 저장되거나 연이어 저장됩니다.
  • Array에서 삽입과 삭제연산은 memory위치가 연속적이고 고정적이기 때문에 많은 시간을 소모합니다.
  • Array는 CompileTime에 메모리에 할당됩니다 ⇒ Static Memory Allocation
  • Stack section에 메모리 할당
  • LinkedList는 Sequential Access를 지원. 접근시 처음부터 순차적인 접근 O(n)
  • 새로운 element들은 memory어딘가에 저장되어 집니다. 저장된 위치주소는 linked list의 이전 node에 저장됩니다.
  • LinkedList의 경우 노드의 경우 각자가 단하나의 위치주소를 가지고 있기때문에 삭제와 추가가 빠릅니다
  • LinkedList에서는 새로운 node가 추가될때 runtime에 할당되어 집니다 ⇒ Dynamic Memory Allocation
  • Heap section에 memory 할당

# let, var

  • var는 재할당이 가능합니다.
  • let은 재할당이 불가능하지만 클래스의 경우 내부값은 수정이 가능합니다.

# Optional

  • 값이 없을수 있음에 대한 명확한 인지를 제공합니다.
  • 런타임에 nil로 인한 문제를 컴파일 단계에서 예방합니다.
  • Obj-c에는 아직 nil타입이 존재하기 때문에 혼용해서 사용하는 경우가 많아 필수입니다.

# Optional Chaning

  • nil인지 아닌지를 판별하고 nil일때와 nil이 아닐때를 분기합니다.

# ?, ??, !

  • ?는 주로 타입캐스팅에 사용되며 맞으면 코드를 연계하고 틀리면 nil이 반환됩니다.
  • ??는 nil일 경우를 대비해 default값을 지정할때 사용합니다.
  • !는 강제적으로 값을 할당할때 사용합니다.

# Protocol

  • 어떤 기능을 이용할때 반드시 포함해야 하는 것을 정해두는 것
  • 뷰끼리 데이터를 넘길때에 사용됩니다 (Delegate)
  • 스스로 기능을 구현하지 않습니다. 제시할뿐.
  • 특정기능을 하기위한 요구사항

# Extension

  • String, Date, Color 등에 Extension을 이용해서 사용자가 편의성을 위해 코드를 확장할수 있습니다
  • 코드의 가독성을 높이기 위해 이용하기도 합니다. (Class)

# Struct와 Class의 차이

  • Struct
    • Value Type ⇒ Stack Memory
    • 상속불가능 ( Protocol은 사용가능 )
    • 멀티 스레딩에 안전
    • 불변성 구현에 유리
    • 크지않은 데이터 모델을 사용할때에 사용
  • Class
    • Reference Type ⇒ Heap Memory
    • ARC가 메모리를 자동으로 관리
    • 멀티스레딩시 적절한 Lock활용필요
    • 상속가능

# Stack

  • 메모리 할당이 컴파일 때만 발생합니다.
  • Stack은 메소드가 실행될때 변수가 POP되고 실행이 종료되면 Push됩니다.
  • CPU에 의해 자동으로 관리됩니다.
  • 크기가 제한되고, 변수크기를 조정불가합니다.
  • 매우 빠르게 액세스됩니다.

# Heap

  • CPU에 의해 자동관리 되지 않기때문에 ARC가 담당해서 관리합니다.
  • 변수는 전역으로 액세스가능합니다.
  • 상대적으로 느리게 액세스 됩니다.

# 접근제어

  • 모듈과 소스파일의 개념에 기반합니다.
  • 모듈이란 import를 통해 다른 모듈로부터 불러들일수 있는 하나의 코드묶음 단위입니다.
  • 소스파일이란 모듈내에 포함된 Swift파일을 의미합니다
    • Private ⇒ 선언된 블록 내에서 접근가능합니다
    • FilePrivate ⇒ 같은 파일 내에서 접근가능합니다.
    • Internal (Default) ⇒ 같은 모듈 내에서 접근가능합니다.
    • Open ⇒ 모듈 밖에서 접근가능합니다 다른 모듈에서 상속, override가능합니다. ( UIKit )
    • Public ⇒ 모듈 밖에서 접근 가능합니다. 상속, override불가능 합니다.

# ARC

  • Retain Count를 이용해 메모리를 관리합니다.
  • Weak
    • 소유권을 가지지 않고 포인터의 주소값 만을 갖습니다.
    • 소유권이 없으므로 retain Count를 증가시키지 않습니다.
    • 메모리가 해제될경우 자동으로 nil로 초기화됩니다.
      ⇒ 따라서 Optional값에만 Weak를 사용할수 있습니다.
    • Delegate, Closure에 주로 사용됩니다.
  • Unowened
    • 해당 인스턴스의 소유권을 갖지 않습니다.
    • retain Count를 증가시키지 않습니다.
    • nil이 될수 없습니다.
  • 차이점
    • Weak는 객체를 계속 추적 후에 nil로 전환합니다.
    • Unowened는 객체가 사라지면 댕글링 포인터가 남습니다.
      ⇒ nil을 가리키는 주소값만이 남으므로 참조할시에 크래시가 발생하기 때문에 사용자의 주의가 필요합니다.

# 고차함수

  • 고차함수란 함수를 매개변수로 받는 함수를 말한다
  • Map
    • 데이터를 변형할때 사용되며 기존 데이터를 변형하지 않습니다.
  • Filter
    • 컨테이너 내부의 값을 재구성 할때 사용합니다. 기존 데이터를 변형하지 않습니다.
    • 리턴값이 true일때 포함하고 false일때 배제합니다.
  • Reduce
    • 데이터를 하나로 합칠때 사용합니다.
    • 초기값을 줄수도있고 안줄수도 있습니다.

# escaping Closure

  • Swift 3 부터는 기본적으로 함수의 인자로 들어온 클로저가 함수 밖에서 실행될수 없습니다.
  • 따라서 @escaping을 붙이면 함수밖에서 실행가능합니다.

# 동적인 TableViewCell

  • 동적인 TableViewCell을 만들기 위해서는 두가지 처리가 필요합니다.
  1. Prototype Cell의 경우 Height는 TableView.rowHeight를 기반으로 합니다.
    ⇒ 따라서 ViewDidload에 tableView.rowHeight = UITableViewAutomaticDimention을 선언해야 합니다.
  2. estimatedRowHeight
    • ViewDidload에서 직접 설정해도되고 Delegate 메서드를 작성해서 처리할수도 있습니다.
    • 이값을 제대로 입력해주지 않으면 셀의 위치가 올바로 생성되지 않을수 있습니다.

# 생명주기 - ViewController

  1. LoadView
    • 뷰컨트롤러가 생성되고 순차적으로 완성되었을때 생성
  2. ViewDidLoad
    • 컨트롤러의 뷰가 메모리에 올라간뒤 호출. 뷰가 '생성' 될때 호출
  3. ViewWillappear
    • 화면에 뷰가 표시될때
    • ViewWillLayoutSubViews ⇒ frame이 바뀔대 호출, 자식뷰의 레이아웃에 영향을 줄때 알립니다.
    • ViewDidLayoutSubViews ⇒ 뷰가 자식뷰의 레이아웃을 바꾸고 난 뒤에 호출되며, 추가적인 변경을 하고싶을때 사용하빈다.
    • 뷰의 계층, frames, bounds 가 모두 세팅 되었다고 생각하면 됨
  4. ViewDidappear
    • 뷰가 화면에 나타나고 호출
    • 여기서 애니메이션 시작등을 시작하면 좋은 장소임
  5. ViewWillDisappear
    • 뷰가 사라지기 직전에 호출
    • 여기서는 아직 완료가 되지 않은, 사용자 데이터를 저장하고, 네트워크 작업을 캔슬하기 좋은 곳입니다.
  6. ViewDidDisappear
    • 뷰가 제거되면 호출
  • 1 → 2 → 1

# App의 생명주기

iOS 13 이상은 UISceneDelegate 개체를 사용하여 scene-based app에서 발생하는 life-cycle event에 응답하면 된다.
iOS 12 이하는 life-cycle event에 응답하기 위해서 UIApplicationDelegate 개체를 사용하면 된다.

  1. Not Running : App이 아직 실행되지 않았거나 System에 의해 종료된 상태.
  2. Inactive : App이 Foreground상태에 있지만 아직 Event를 받지 않은 상태.
  • 일반적으로 다른 상태로 전환될 때 잠시 동안만 이 상태를 유지한다.
  1. Active : App이 Foreground상태에 있고 Event를 받은 상태.
  2. Background : App이 Background상태에 있지만 Code가 있는 상태.
  3. Suspended : App이 Background상태에 있고 동작하는 Code가 없는 상태.
  • System은 App을 자동으로 이 상태로 만들고 Memory에는 유지. 하지만 Memory 부족 상태가 나타나면 Memory에서 제거.

  • State

    • iOS 13 이상은 UISceneDelegate 개체를 사용하여 scene-based app에서 발생하는 life-cycle event에 응답하면 된다.
    • iOS 12 이하는 life-cycle event에 응답하기 위해서 UIApplicationDelegate 개체를 사용하면 된다.
    • Foreground :
      • user가 사용하고 있기 때문에 user의 관심을 받게되고 따라서 CPU를 포함한 system resource에서 우선순위를 가지게 됩니다.
    • Background
      • 화면의 밖의 일이기 때문에 가능한 작업을 수행하지 않는것이 좋습니다.
  • AppDelegate

    • ios 12이하의 역할
      • 앱의 주요 lifeCycle 이벤트를 처리했습니다. ( State관리 )
    • 13이상의 역할
      1. 앱의 중앙 데이터 구조를 초기화
      2. 앱의 scene을 구성(Configuration)
      3. 밖에서 발생한 알림(배터리 부족, 다운로드 완료 등)에 대응
      4. 앱의 scenes, views, view controllers에 한정 되지 않고 앱 스스로를 타겟하는 이벤트에 대응
      5. 애플 푸쉬 알림 서비스와 같이 앱이 시작할 때 요구되는 모든 서비스를 등록

# GCD

  • Multicore Process를 위한 Thread Programing의 방법입니다.
  • 스레드를 관리하면서 동시적으로 작업을 실행시키는 애플이 지원하는 저수준 API를 제공하는 라이브러리입니다.
  • 스레드 풀의 관리를 OS가 하기떄문에 프로그래머가 Task를 생성하고 Queue에 추가하면 GCD는 Task에 맞는 스레드를 자동으로 생성하고 실행하여 종료되면 제거합니다.
    • DispatchQueue : 기본적으로 FIFO순서로 실행됩니다. ⇒ 순차적실행과 동시 수행
    • Seriel DispatchQueue : 한번에 하나의 작업만 수행하고 끝나기를 기다립니다 ⇒ 순차적실행 완료를 대기
    • ConCurrent DispatchQueue : 가능한 많은 작업을 실행하고 수행합니다.

# Async & Sync

  • Async : 순서에 상관없이 여러 Task를 동시처리 합니다.
  • Sync: 하나의 작업이 끝나면 순차적으로 실행후 처리합니다.

# Thread

  • 하나의 프로세스 내에서 실행되는 작업흐름의 단위로 프로세스가 시작하는 동시에 작동하는 스레드를 main스레드 이외를 sub스레드라고 합니다.
  • MultiThread
    • 여러개의 스레드가 동시에 진행되는 것을 말합니다. 하나의 프로세스안에 여러개의 스레드가 존재하고 이 스레드가 프로세서의 자원은 공유하되 실행은 독립적으로 처리되는 구조입니다.

# enum / function / closure 각각 value type 인가 reference type 인가?

  • Enum은 Value타입입니다.
  • Function과 Closure는 reference Type입니다.

# 디바이스가 없을 경우 개발 환경에서 할 수 있는 것과 없는 것

  • 화면적인 차이점
    • 해상도 또는 포인트 당 픽셀수의 차이점
    • Mac화면의 색상 영역이 다를 수 있어서 실제 색상과 부정확 할수 있다.
  • 시스템적인 차이점
    • 시뮬레이터는 iOS11이상, tvOS11이상, watchOS4 이상에서 백그라운드의 앱들과 프로세스들을 일시 중단 시키나 디버거에 의해 다시 재개시킬수 있다
    • 시뮬레이터는 HFS+와 APFS포멧으로 된 볼륨에서 대소문자를 구분하는 파일스스템으로 처리
  • 하드웨어적인 차이점
    • 시뮬레이터에서 지원하지 않는 하드웨어
      1. 주변 광 센서
      2. 오디오 입력
      3. 기압계
      4. 블루투스
      5. 카메라
      6. 모션 지원
      7. 근접 센서
  • API에서의 차이점
    • 일부 frameworks는 시뮬레이터에서 지원하지 않습니다.
      1. ARKit
      2. External Accessory
      3. HomeKit
      4. IOSurface
      5. Media Player
      6. Message UI

# Foreground & background

  • Foreground : 사용자가 앱을 보고있는 화면입니다.
  • Background : 앱이 홈화면에 들어가서 사용자한테 보이지 않는 상태를 의미합니다.
    ⇒ 앱이 뒤에서 실행되고 있는상태

# 앱이 foreground에 있을 때와 background에 있을 때 어떤 제약사항이 있나요?

https://medium.com/cashwalk/ios-background-mode-9bf921f1c55b

  • 1. Not Running
    • App을 실행하지 않은 상태로서, App이 실행되기전 상태 또는 실행되었지만 System에 의해 종료된 상태입니다.
  • 2. Foreground
    • App이 실행되어 사용자에게 보여지고 있는 상태입니다.
    • 오직 하나의 App만 Foreground 상태를 가지며 inActive와 Active의 두가지 상태로 나뉘어집니다.
    • InActive : Foreground 상태에서 전화가 왔을때, 잠금상태, 멀티태스킹 스크린에서는 InActive 상태를 가집니다.
    • Active : inActive 상태가 아닌 상태에 해당합니다.
  • 3. Background
    • Foreground 상태에서 HomeScreen으로 이동한 상태입니다.
    • Background 상태로 전환되기 전에 호출된 Task가 끝나지 않은 경우 Background 상태에서도 여전히 실행됩니다.
    • Background 상태로 전환된 후 호출된 Task는 App이 Foreground 상태로 전환된 후에 실행됩니다.
  • 4. Suspend
    • App이 Background 상태로 전환된 후 더 이상 작업을 수행하지 않으면 System에서 App을 Suspend 상태로 바꾸게 됩니다.
    • App은 여전히 메모리에 존재하며 Suspend 상태가 될 당시의 상태를 저장하고 있지만, CPU나 배터리를 소모하지 않습니다.
    • Suspend 상태의 App은 Foreground 상태의 App을 위해 메모리 부족 등의 이유로 System에 의해 언제든지 종료됩니다. 이후 App을 실행하면 이전 상태의 화면은 나오지 않고 App이 재시작됩니다.
  • 백그라운드 작업 지원하도록 선택가능

# NSOperationQueue과 DispatchQueue의 차이점

  • GCD는 C API 기반
    • 취소하려면 부수적인 코드가 많이 작성됩니다.
    • 우선순위가 존재하지만 같은 작업에서 우선순위를 부여할수 없습니다.
    • 개별 블럭이 아닌 전체큐에 대한 우선순위를 설정합니다.
  • NSOperationQueue는 Objective C API 기반
    • 장점은 취소가 쉽습니다
    • 다소 무겁습니다.
    • isCancelled, isFinished 등을 이용해 상태를 체크할수 있습니다.
    • 재사용할수 있습니다.
    • 같은 작업간에 우선순위를 부여할수 있습니다.

# Foundation Kit & UIKit

  • 프로그램의 중심을 담당하는 프레임워크입니다.
  • 원시 데이터 타입 ( String, Int, Double) 이 포함되어있기 때문에 이 프레임워크를 상속하지 않으면 아무것도 할수 없습니다.
    • 상세설명
  • UIKit은 Core Services를 상속했기 때문에 UIKit만 import해도 Foundation을 사용할수 있습니다.
    • UIKit은 화면을 구성하기 위한 필수적인 프레임워크입니다.
  • 계층구조

  1. Core OS계층
    • 커널, 파일 시스템, 네트웤, 보안, 전원 관리, 디바이스 드라이버 등이 포함
    • iOS가 운영 체제로서 기능을 하기 위한 핵심적인 영역
  2. Core Service 계층
    • 문자열 처리, 데이터 집합 관리, 네트워크 , 주소록 관리, 환경 설정 등 핵심적인 서비스들을 제공
    • GPS, 나침반, 가속도 센서나 자이로스코프 센서와 같이 디바이스의 하드웨어 특성에 기반한 서비스도 제공
      • Foundation, Core Foundation, Core Location, Core Motion, Core Animation, CoreData
  3. Media 계층
    • 상위 계층인 코코아 터치 계층에 그래픽 관련 서비스나 멀티미디어 관련 서비스를 제공
    • Core Graphics, Core Text, Core Audio, Core Animation, AVFoundation
  4. Cocoa Touch 계층
    • 하위 계층의 프레임워크를 사용하여 애플리케이션을 직접 구현하는 프레임워크
    • UIKit, GameKit, MapKit

# AppDelegate & SceneDelegate

AppDelegate ⇒ Process LifeCycle, Session LifeCycle
SceneDelegate ⇒ UILifeCycle

  • ios12이하에서

  • iOS13 이후

  • iOS12까지는 대부분 하나의 앱에 하나의 window 였지만 iOS 13부터는 window의 개념이 Scene으로 대체되고 아래의사진처럼 하나의 앱에서 여러개의 Scene을 가질수 있습니다.

  • 기존 AppDelegate의 역할을( UI의 상태를 알수 있는 UILifeCycle에 대한 부분) SceneDelegate로 전환
  • AppDelegate에 Session LifeCycle에 대한 역할 추가 ( Scene Session이 생성되거나 삭제될때 AppDelegate에 알리는 두 메소드가 추가되었습니다.)
    ⇒ Scene Session은 앱에서 성성한 모든 Scene의 정보를 관리

  • Scene

    • Scene에는 UI의 하나의 인스턴스를 나타내는 windows와 viewControllers가 들어있습니다.
    • 각 Scene에 해당하는 UIWindowSceneDelegate객체를 가지고 있고 이 객체는 UIKit와 앱 간의 상호작용을 조정하는데 사용합니다.
      • 결과적으로 하나의 앱은 여러 Scene과 Scene Delegate 객체를 동시에 활성화 할수 있습니다.
  • Scene Session?

    • 사용자가 앱에 새로운 Scene을 추가하거나 프로그래밍적으로 Scene을 요청하면 시스템은 그 scene을 추적하는 session 객체를 생성합니다. 그 session에는 고유한 식별자와 scene의 구성 세부사항이 들어있습니다.
  • AppDelegate

    • 이전에는 앱이 foreground에 들어가거나 background로 이동할 때 앱의 상태를 업데이트하는 등의 앱의 주요생명주기 이벤트를 관리했었지만 더이상 하지 않습니다.

      • iOS 13이후의 5가지 일

        1. 앱의 가장 중요한 데이터 구조를 초기화하는 것
        2. 앱의 scene을 환경설정(Configuration)하는 것
        3. 앱 밖에서 발생한 알림(배터리부족, 다운로드 완료 등)에 대응하는 것
        4. 특정한 scenes, views, viewControllers에 한정되지 않고 앱 자체를 타겟하는 이벤트에 대응하는 것
        5. 애플 푸쉬 알림 서비스와 같이 실행시 요구되는 모든 서비스를 등록하는 것
        • UIApplicationDelegate

  • Deployment Target이 iOS 13 미만인 상황에서는?

# 앱 실행시 작동 순서

  1. App Touch
  2. main() 안에서 UIApplicationMain() 호출 , UIApplication 객체 생성
  3. UIApplication 객체는 info.plist 파일으로부터 앱에 필요한 데이터와 객체들을 로드
  4. 커스텀 코드를 처리하기 위한 AppDelegate를 생성하고 이를 UIApplication 객체와 연결
  5. 실행을 준비하고 application(_: willFinishLaunchingWithOptions:) 호출
  6. 준비가 끝나고 앱 실행 직전에
    application(_: didFinishLaunchingWithOptions:) 호출
  7. Main run loop실행, 이벤트 큐를 이용해 이벤트 순차 처리
  8. 앱을 더이상 사용하지 않으면 iOS System에 terminate 메시지 전달
    applicationWillTerminate(_:) 호출
  9. APP 종료
  • 앱이 실행될때 Backgroud에서 시작하면 InActive를 거치지않고 실행된다.
  • Active상태에서 Backgroud상태로 바뀌기전에 InAtctive를 거친다

# CGPoint, CGRect, CGSize

  • CGPoint ⇒ CGPoint(x: ?, y: ?) / 2차원 좌표계의 점을 포함하는 구조체
  • CGSize ⇒ CGSize( width: CGFloat, height: CGFloat ) / 너비와 높이 값을 포함하는 구조체
  • CGRect ⇒ CGRect(x, y, width, height ) / 사각형의 위치와 크기를 포함하는 구조체

# Frame 과 Bound

  • Frame
    • SuperView(상위뷰)의 좌표시스템 안에서 View의 위치와 크기를 나타냅니다
    • 이때 상위뷰는 최상위 뷰가 아니라 현재 뷰의 상위뷰를 말합니다.
    • 뷰의 위치와 크기를 정해줄때 사용합니다
  • Bound
    • View의 위치와 크기를 자신만의 좌표시스템 안에서 나타냅니다
    • 바운드를 변경하는 것은 해당위치에서 View를 다시그리라는 의미입니다.
    • 스크롤뷰가 스크롤하는 것은 바운드값을 변경해서 뷰가 그려질 위치를 지정하는 것입니다.
    • 디폴트값은 (0, 0) 입니다
    • 하나의 큰 사진이 있을때 그려질 위치를 지정하는 것이라고 보면 편합니다.

# MVC, MVVM

  • MVC
    • Model - View - Controller
    • 장점
      • 유연하고 확장하기 쉽다
      • 유지보수 비용을 절감할 수 있다
      • 디자이너와 개발자의 협업이 용이하다
    • 단점
      • Model과 View의 완벽한 분리가 어렵다
      • 기본기능 설계를 위해 클래스들이 많이 필요하기 때문에 복잡할 수 있다
      • 의존성이 높아 유지보수가 어렵다

  • MVVM
    • Model - View - ViewModel
    • 의존성 최소화
    • ViewModel의 설계가 쉽지 않습니다. ( Data Binding )

# CustomView

https://seonift.github.io/2018/05/23/Swift-커스텀-UIView-제작하기-with-Xib/

# UIKit

  • 코코아터치에서는 UIApplication 스레드가 UIApplicationMain()의 진입점 함수에 의해 생성되기 때문에 애플리케이션의 인스턴스가 메인 스레드에 연결됩니다.
  • For the most part, UIKit classes should be used only from an application’s main thread. This is particularly true for classes derived from UIResponder or that involve manipulating your application’s user interface in any way. ( 많은 것들이 UIResponder와 유저인터페이스와 연관되어 있기 때문에)

# 하나의 뷰컨트롤러에서 여러 테이블뷰가 사용될때

myTableView1.dataSource = self;
...

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  if (tableView == myTableView1) {
    // your code 1
  }
  else 
  if (tableView == myTableView2) {
      // your code 2
  }
  else 
  if (tableView == myTableView3) {
      // your code 3
  }
}

# 번들구조

https://melod-it.gitbook.io/sagwa/documentation-archive/bundle-programming-guide/bundle-structures