https://in.swiftui.wtf/great 조건식 보다는 모디파이어를 선호하라 - 애니메이션 보간 가능하게하고, 성능 향상에 도움이 됨 - 뷰 트리를 유지하는지, 바꾸는지의 차이 "브랜치는 훌륭하며, SwiftUI에는 이유가 있다. 하지만 불필요하게 사용될 때, 그들은 열악한 성능, 놀라운 애니메이션, 그리고 심지어 상태 손실을 초래할 수 있다. 브랜치를 도입할 때, 잠시 멈추고 여러 뷰를 나타내는지 아니면 같은 뷰의 두 상태를 나타내는지 고려하세요." 관련영상 https://developer.apple.com/videos/play/wwdc2021/10022/?time=1498 State and dependencies - let 을 우선으로 사용하라 - 부모 뷰로 부터 값을 전달 받고 이 값을 ..
Xcode에서 프로젝트 빌드시 다음의 파생 데이터들이 발생하게 됩니다 폴더 경로: (~/Library/Developer/Xcode/DerivedData) - Intermediate Build Results - Generated Indexes - Module Caches - Logs - Symbol Caches 이러한 파생 데이터들은 Xcode는 빌드 과정을 최적화하고 빌드 시간을 단축하는 용도로 사용됩니다 하지만 파생 데이터는 캐싱된 데이터로 인해 가끔 설명할 수 없는 오류들을 발생시킬 수 있기 때문에 삭제해주어야 할 경우가 생기게 됩니다 DerivedData를 삭제하는 방법은 다음과 같습니다 1. Xcode 클린 빌드(command + shift + k) * 프로세스 점유, 권한 문제 등으로 완전히 지..
AppStore의 App 탭의 각 섹션을 나타내는 뷰를 유사하게 만들어보고자 합니다. 요구 사항으로는 Scroll Snap이 가능하며, 스크롤시 양 옆의 콘텐츠 일부가 노출되어야 합니다. 일반적으로 해당 기능을 수행하는 뷰를 Carousel View라고 명칭하는 것 같습니다. Carousel View를 분석한 구조는 다음과 같습니다. - horizontal spacing: 콘텐츠 전체 영역이 시작되고 끝나는 지점을 정의합니다. - spacing: 각 콘텐츠 영역 사이의 마진 값 입니다. - visible rect: 부모 뷰에서 바라보는 사각형 영역 입니다. - scrollOffsetX: x축의 오프셋 값 입니다. Carousel View는 visible rect를 오프셋을 이동시키며 콘텐츠 뷰를 순서대로..
프로그램이 실행을 위해 물리 메모리에 적재되면 CPU는 프로세스를 위한 독자적인 주소공간을 생성합니다. 이 주소를 논리적 주소(=가상 주소)라고 하고 각 프로세스마다 독립적으로 할당됩니다. CPU가 기계어 명령을 수행하기 위해서는 논리적 주소에 근거해 매핑된 물리적 메모리 위치를 확인해야 합니다. 메모리에 적재된 프로세스의 논리적 주소를 물리적 주소로 연결시켜주는 작업인 주소 바인딩에 대해 알아보겠습니다. 주소 바인딩 프로세스의 논리적 주소를 물리적 메모리 주소로 연결시켜주는 작업을 주소 바인딩이라고 합니다. 프로그램이 적재되는 물리적 메모리의 주소가 언제 결정되느냐에 따라 세 가지로 분류할 수 있습니다. 컴파일 타임 바인딩 로드 타임 바인딩 실행 시간 바인딩 컴파일 타임 바인딩 컴파일을 하는 시점에 해..
연속 할당 방식 프로그램을 메모리에 올릴 때, 물리적 메모리의 한 곳에 연속적으로 적재하는 방식으로 고정 분할 방식과 가변 분할 방식이 존재합니다. 고정 분할 방식 주어진 개수 만큼의 영구적인 분할로 미리 나누어 두고 각 분할에 하나의 프로그램을 적재하는 방식입니다. 이 분할의 크기를 모두 동일하게 할 수도 있고 서로 다르게 할 수도 있습니다. 하나의 분할에는 하나의 프로그램만 적재 가능하므로 외부 조각과 내부 조각이 발생합니다. 외부 조각 프로그램의 크기 > 분할의 크기인 경우 발생합니다. 프로그램을 적재하지 못하는 빈 메모리 공간으로 사용될 수 없는 작은 분할을 의미합니다. 내부 조각 프로그램의 크기 < 분할의 크기인 경우 발생합니다. 프로그램이 분할에 적재되고 나서 분할 내부에 사용될 수 없는 메모..
Sandboxed App iOS 앱은 샌드 박스에 의해 제한되므로 앱은 일반적으로 해당 앱에서 만든 파일에만 접근할 수 있습니다. (앱은 주소록 데이터 및 사진과 같은 특정 다른 파일에 접근할 수 있지만 해당 용도로 특별히 설계된 API를 통해서만 가능합니다.) 또한 iOS 기기에서 파일 보호가 활성화 된 경우 앱은 기기가 잠겨있을 때 특정 파일에 대한 접근을 차단하도록 선택할 수 있습니다 보안상의 이유로 iOS 앱과 파일 시스템의 상호 작용은 앱의 샌드박스 디렉토리 내에 있는 디렉토리로 제한됩니다. 새 앱을 설치하는 동안 설치 프로그램은 샌드박스 디렉토리 내에 앱에 대한 여러 컨테이너 디렉토리를 만듭니다. 각 컨테이너 디렉토리에는 특정 역할이 있습니다. 번들 컨테이너 디렉토리는 앱의 번들을 보유하고 데..
캐시란 캐시는 애플리케이션의 성능을 크게 향상시킬 수 있는 객체 또는 데이터 모음입니다. 캐시를 사용함으로써 계산 비용이 많이 들 수 있는 일시적인 데이터와 함께 자주 접근하는 객체를 저장할 수 있습니다. 캐싱된 객체를 다시 사용하면 해당 값을 다시 계산할 필요가 없기 때문에 성능상의 이점을 얻을 수 있습니다. 그러나 특정 상황에서 몇가지 가능한 단점 또한 존재합니다. 많은 대용량 데이터를 캐싱할 때 다른 애플리케이션을 위한 RAM이 남아 있지 않을 정도 많은 객체를 캐시할 수 있으며, RAM을 확보하기 위해 애플리케이션을 종료할 수 있습니다. iOS에서는 캐싱을 위한 NSCache 객체를 제공하며 생성 비용이 많은 객체를 임시로 저장할 수 있습니다. 이번 포스팅에서는 NSCache와 Purgeable ..
OptionSet 이란 OptionSet은 Enum 타입과 유사하지만 한 번에 둘 이상의 상태를 나타낼 수 있습니다. OptionSet 프로토콜을 준수하여 비트 마스킹이 가능하고 개별 비트 집합을 표현할 수 있습니다. 참고로 문서에 따르면 Apple SDK의 300개 이상의 타입에서 사용되고 있습니다. 서브 뷰의 autoresizing을 적용하려는 상황을 가정해보겠습니다. subview.autoresizingMask = [] subview.autoresizingMask = .flexibleTopMargin subview.autoresizingMask = [.flexibleLeftMargin, .flexibleTopMargin] OptionSet은 SetAlgebra 프로토콜을 준수하기 때문에 Set 자료..
간단한 xcrun simctl 명령어를 통해 실행 중인 시뮬레이터의 앱 내 Document 폴더를 확인할 수 있습니다. 1. iOS 시뮬레이터를 실행합니다. 2. `xcrun simctl` 명령어를 사용하여 현재 실행중인 iOS 시뮬레이터 앱 폴더 경로를 확인할 수 있습니다. (my.app.identifier 대신 앱의 bundle ID를 입력합니다.) xcrun simctl get_app_container booted my.app.identifier data 3. 현재 실행중인 iOS 시뮬레이터 앱 폴더 경로로 이동 후 Document 폴더를 확인할 수 있습니다. cd $(xcrun simctl get_app_container booted my.app.identifier data) open . 출처 w..
Render loop란 유저가 앱과 상호작용하기 시작할 때, 새로운 프레임이 렌더링된다. (아이폰 또는 아이패드 유저는 60Hz 프레임 레이트를 갖는다. 각 프레임 시간은 16.67ms(1/60)이다.) 이렇게 화면에 새 프레임을 렌더링하는 주기를 “Render loop" 라고 한다. Render loop의 목적은 모든 뷰가 모든 프레임에 대해 의도한대로 표시되도록하는 것이고 이 구성 요소를 이해하면 레이아웃 변경과 같은 가능한 함정에 빠지지 않게 된다. 또한 중복 작업을 피하는 데 매우 유용하다. Render loop는 다음의 세 단계로 구성된다. 1. Update Constraints (레이아웃 계산) 2. Layout (이전 단계의 레이아웃 값을 뷰에 입력) 3. Display (레이아웃 bound..
description property var description: String { get } description 프로퍼티를 통해 인스턴스의 텍스트 표현을 할 수 있습니다. print(_:) 함수로 인스턴스를 출력하고자 할 때, 인스턴스의 description 프로퍼티를 사용합니다. 그렇다는 것은 인스턴스 내부에 description을 정의해주지 않아도 이미 구현이 되어있다는 것입니다. 예를 들면, CGFloat 데이터 타입에는 description property가 구현되어 있음을 확인할 수 있었습니다. extension CGFloat : CustomStringConvertible { /// A textual representation of `self`. public var description: S..
UITableView 또는 UICollectionView와 같이 콘텐츠 영역을 스크롤링 가능한 스택 뷰를 만들어보고자 합니다. Storyboard 구현 및 소스 코드 구현 방법을 차례대로 작성하였습니다. Storyboard 구현 1. Vertical StackView를 추가하고 StackView의 subviews로 4개의 이미지 뷰를 순서대로 추가합니다. 2. StackView를 선택하고 상단 메뉴에서 Editor > Embed In > Stack View 를 선택하여 ScrollView를 Embed 합니다. 3. StackView가 스크롤 뷰의 가로, 세로 영역에 맞게 떨어지도록 오토레이아웃을 설정합니다. StackView를 선택하고 오른쪽 하단 3번째 아이콘(Resolve Auto Layout Iss..