본문 바로가기

전체 글97

Swift 제네릭(Generics) 문법 알아보기 제네릭 문법 형식에 관계없이, 한 번의 구현으로 모든 타입을 처리하여 타입에 유연한 함수를 작성하는 문법이다. 유지보수 및 재사용성이 증가하는 장점이 있다. 함수뿐만 아니라 구조체, 클래스, 열거형도 제네릭으로 일반화가 가능하다. 제네릭 문법이 필요한 이유 타입만 다르고 구현 내용이 동일한 경우, 제네릭이 없다면 타입마다 모든 경우를 다 정의해줘야 한다. 개발자의 일이 늘고, 유지보수 및 재사용성이 어렵게 만들기 때문이다. 제네릭 함수의 정의 func genericsFunc(array: [T]){ // code } 는 타입 파라미터라고 한다. 함수 내부에서 파라미터의 타입이나 리턴형으로 사용된다. 관습적으로 Type의 의미인 T를 사용하기도 하지만, 다른 문자를 사용해도 된다. (형식 이름이기 때문에 U.. 2023. 8. 11.
iOS 화면 시스템 (프레임 vs 오토레이아웃) iOS는 프레임 방식에서 오토레이아웃 방식으로 발전되었고, 2가지 시스템이 공존한다. 프레임(frame) 상위 뷰를 기준으로 위치(position), 크기(size), 원점을 origin으로 표기 고정 (화면 왼쪽 상단 or 상위 뷰 기준) 여러 크기의 화면 대응 불가 (가능하나 불편 - 화면 크기를 불러와서 비율로 재계산) 타입: CGRect = CGPoint + CGSize 오토레이아웃(제약 - constraints) 제약조건을 활용해 정렬(Alignment), 고정(Pinning), anchor 상대적 / 동적 여러 크기의 화면 대응이 쉬움 NSLayoutConstraint 현재는 오토레이아웃 결과(화면 크기별로) 프레임으로 다 계산되어 화면에 표시되고 있는 것이다. 또한, 화면 상단과 화면 전환을.. 2023. 8. 10.
Xcode MARK, 코드 스니펫 설정하는 법 실무는 코드가 굉장히 길기 때문에 원하는 코드를 찾기가 어렵다. 때문에 MARK를 사용하여 기록해놓고, 추후 빠르게 해당 부분을 찾는다. MARK는 아래와 같은 형태로 입력한다. // MARK: - 이메일 박스 그리고 Xcode의 해당 부분을 클릭하면 마크가 위와 같이 보여진다. 반복되는 입력을 간단히 하기 위해 코드 스니펫을 사용해 더 쉽게 작성할 수 있다. 트랙패드에 두 손가락을 눌러 Create Code Snippet을 누른다. 그럼 나타나는 스니펫 설정 창에서 아래와 같이 입력한다. 참고로 내용입력 부분은 과 같이 입력하면 위와 같이 나온다. 그리고 코드 내 mark를 입력하면 자동 완성이 나온다! 2023. 8. 10.
Swift 에러 처리(Error Handling) 에러는 컴파일 에러와 런타임 에러로 구분할 수 있다. 컴파일 에러는 우리가 코드를 치는 동안 발생하는 문법적 오류들을 XCode에서 알려주는 것들을 말한다. 런타임 에러는 실제 프로그램 실행중에 오류로 인해 앱이 꺼지는 오류를 말한다. 런타임 에러는 사용자들에게 UX 적으로 좋지 못한 경험을 주기 때문에 미리 에러 처리를 통해 런타임 에러를 막아야 한다. 런타임 오류가 발생하는 상황의 예시로는 네트워크 통신을 통해 데이터를 받아와 화면을 표시해야하는데, 데이터를 받아오지 못한 경우 발생할 수 있다. 그럼 런타임 에러가 발생할 때 프로그램이 바로 꺼지는 것이 아닌 유저에게 안내를 해주고 꺼지게 하는 방법은 없을까? [에러 타입 정의] Error는 열거형이므로 미리 정의한 후 사용할 수 있다. 또한 Err.. 2023. 8. 7.
Swift 델리게이트 패턴 이해하기 델리게이트는 객체와 객체 간의 의사소통을 위한 것이다. 예를 들면 텍스트필드와 뷰컨트롤러 간의 의사소통을 하기위해 만드는 것이 바로 델리게이트다. 그리고 의사소통을 하기 위해서 프로토콜을 따라야한다. 해당 프로토콜을 통해 정의된 것들을 구현하면서 텍스트필드에서 일어나는 것들을 뷰 컨트롤러에 전달할 수 있게 된다. 예를들어 리모컨 컨트롤러를 만들고, 이를 다른 기기 컨트롤러와 연결하고자 할 때 필요한 과정을 요약해보자면 1. 리모컨 컨트롤러 사용을 위한 프로토콜을 만든다. protocol RemoteControlDelegate { func powerOn() func powerOff() } 2. 해당 프로토콜을 델리게이트로 이용하는 RemoteControl 클래스를 만든다. 해당 클래스에서는 delegate.. 2023. 8. 7.
Swift 메모리 관리(ARC) 메모리의 구조는 코드, 데이터, 힙, 스택으로 구성되어있다. 코드 영역에는 컴파일된 코드가 들어있다. 데이터 영역에는 전역 변수 혹은 타입 변수 중 클래스와 구조체가 들어있다. 공통으로 공유하기 위한 데이터가 저장되는 영역이다. 힙 영역에는 동적 할당되는 크기가 크고, 관리할 필요가 있는 데이터가 저장되는 영역이다. 스택영역에는 함수가 실행되기 위한 임시적인 공간이다. 스코프가 종료되면 자동으로 제거되기에 관리가 필요없는 영역이다. Swift에서 값 형식은 필요 시 항상 메모리의 값이 복사되어 저장되는데 stack 영역에 저장된다. 그리고 값이 들어있는 스코프가 종료되면 메모리에서 자동으로 제거된다. 하지만, 참조 형식은 필요 시 항상 메모리의 주소를 저장하고 값은 heap 영역에 주소는 stack 영역.. 2023. 8. 6.
Swift 고차함수 (map, filter, reduce) 고차함수 함수를 파라미터로 받거나, 함수의 결과 값으로 함수를 리턴하는 함수 (input이나 output이 함수인 함수) 대표적으로 map, filter, reduce가 있음 (forEach, compactMap, flatMap) Sequance, Collection 프로토콜을 따르는 컬렉션에 기본적으로 구현되어 있는 함수 map 기존 배열의 각 값들을 새롭게 매핑해 새로운 배열을 리턴하는 함수 (매핑 방식은 클로저가 제공) let numbers = [1, 2, 3, 4, 5] // numbers.map(transform: (Int) throw -> T) let newNumbers = numbers.map{num in return num + 1 } // 위와 동일하나 간소화된 문법 // let newN.. 2023. 8. 4.
Swift 클로저(Closure) 클로저란? 이름이 없는 함수를 의미함 왜 이름이 불필요할까? 함수를 실행하는 형태가 아닌 전달하는 형태로 사용하기 때문에 이름이 불필요함 ex) 파라미터 전달 등 함수가 필요한 순간 클로저로 정의해서 전달 함수와 클로저 형태의 비교 // 함수의 형태 func myFunction() -> Int { return ... } // 클로저의 형태 {() -> Int in return } 함수를 1급 객체로 취급함, 함수는 타입! 함수를 변수에 할당할 수 있음 함수를 호출할 때, 함수를 파라미터로 전달할 수 있음 함수에서 함수를 반환할 수 있음 중괄호는 함수 // 아래 두 코드는 동일함을 인지할 수 있어야 함 var sample = { print("closure") } var sample = { () -> () .. 2023. 8. 4.
iOS 앱이 만들어지는 원리 (Web과 비교) iOS는 내부적으로 아주 복잡한 메커니즘이 있지만, 실제로 잘 알지 못해도 쉽게 구현 가능하도록 설계되어 있다. 내부적인 매커니즘(앱의 생명주기, 뷰컨트롤러의 생명주기, Drawing Cycle 등)에 의해 완벽하게 통제된다. 웹은 상단부터 아래로, 영역을 나눠 그린다. 화면을 그리는 메커니즘과 내부 동작 매커니즘이 완전 분리된다. 운영체제와 독립적이고, 브라우저의 엔진에 의해 돌아간다 iOS는 오브젝트(대부분 클래스)들을 올려놓고 배치한다. 배치방법에는 프레임 방식과 오토레이아웃 방식 2가지가 있다. 내부 속성/동작들이 이미 내장되어 있다. 하나의 클래스 내에 그리는 매커니즘과 동작에 대한 매커니즘이 공존한다. 그래서 클래스와 객체지향 개념에서 출발할 수 밖에 없다. 앱을 만드는 것은 운영체제와 밀접한.. 2023. 8. 2.