Project 64

Rust의 Copy와 Clone 차이점 정리

Rust의 Copy와 Clone 차이점 정리Rust의 소유권과 관련하여 Copy와 Clone의 차이점 정리 // 컴파일 Olet x = 5;let y = x;println!("{x}, {y}");// 컴파일 Xlet s1 = String::from("hello");let s2 = s1;println!("{s1}"); 둘 다 값을 다른 변수에 대입했을 뿐인데, 왜 하나는 되고 하나는 안 되는지 이 차이를 설명하는 개념이 Copy와 Clone 목차요약i32는 왜 대입 후에도 사용할 수 있을까?String은 왜 move될까?Copy란?Clone이란?헷갈리는 부분 정리구조체에서 Copy와 Clone 사용하기Copy를 붙일지 판단하는 기준정리 요약구분CopyClone호출 방식암묵적명시적사용 형태let y = x;..

Rust 소유권 (Ownership) 이해하기

Rust 소유권 (Ownership) 이해하기Rust에서 소유권은 단순한 문법이 아니라 메모리를 관리하는 기본 규칙. Rust는 GC가 메모리를 정리하는 방식도 아니고, 개발자가 직접 free를 호출하는 방식도 아님. 대신 컴파일 시점에 값의 owner, scope, 참조 관계를 검사해서 메모리 안전성을 보장. 목차Rust가 메모리를 관리하는 방식소유권 규칙Stack과 HeapMove, Clone, Copy함수 호출과 소유권 이동참조와 빌림Mutable reference 규칙Dangling reference를 막는 방식Slice 타입 Rust가 소유권을 사용하는 이유프로그램은 실행 중에 메모리를 사용함.문제는 사용이 끝난 메모리를 언제 정리할지임. 언어마다 이 문제를 푸는 방식이 다름.GC가 있는 언어는..

클로저 안에 락을 두어 생기는 데드락 (Apple 시스템 API)

클로저 안에 락을 두어 생기는 데드락 (Apple 시스템 API) 클로저 안에 락이 들어 있으면 위험함. 획득이든 해제든 락의 수명이 클로저 실행에 묶이는데, 클로저가 언제 불릴지, 혹은 불리지 않을지 앱이 통제하지 못하기 때문. 애플 시스템 API를 쓰는 영역에서 이 형태로 데드락이 발생. lock을 잡고 시스템 API를 호출한 뒤 완료 클로저 안에서 unlock을 하던 기존 코드였음. 그 클로저가 끝내 호출되지 않으면 lock이 풀리지 않아 무한 대기에 빠짐. 완료 클로저 안의 unlock이 실행되지 않는 경우락을 잡은 채로 완료 클로저 안에서만 unlock을 하는 형태로 실제 코드를 단순화하면 아래와 같음. func activateAudioSession() { lock.lock() // ..

기기별 RAM 용량에 따른 이미지 동적 캐시 사이즈 설계

기기별 RAM 용량에 따른 이미지 동적 캐시 사이즈 설계 글로벌 서비스를 운영하다 보면, 여전히 RAM 2GB~3GB 수준의 구형 기기 사용자를 무시할 수 없음. iPhone 8, iPhone SE 1세대, 일부 보급형 기기처럼 메모리 여유가 크지 않은 환경에서는, 캐시 전략 하나만으로도 앱 안정성이 크게 달라질 수 있음. 이미지 캐시는 사용자 경험을 빠르게 만들기 위한 중요한 장치지만, 동시에 메모리를 많이 사용하는 기능이기도 함. 그래서 캐시 크기를 고정값으로 두면 다음과 같은 문제가 생김 저사양 기기에서는 메모리 압박으로 크래시 위험이 커짐고사양 기기에서는 더 많은 자원을 활용하지 못해 비효율이 발생함 기기의 물리적 RAM 용량을 기준으로 이미지 캐시 사이즈를 동적으로 결정하는 방식을 적용 왜 동적..

HTTPURLResponse.allHeaderFields 파싱 시 NSNumber 헤더 누락 문제

HTTPURLResponse.allHeaderFields 파싱 시 NSNumber 헤더 누락 문제 네트워크 응답 처리 레이어에서 `HTTPURLResponse.allHeaderFields`를 [String: String] 형태로 변환해 상위 모듈에 전달.기존 변환 사용 로직은 Any를 `as? String`으로 캐스팅하는 방식인데, 이 방식이 Swift 타입 시스템과 Foundation의 NSNumber 브리징 동작이 결합되어 일부 헤더를 조용히 누락시키는 현상 코드 예시참고로 헤더에는 동일한 key가 중복을 허용하고 있어서 header는 동일 키 값에 대해서도 여러개 받을 수 있도록 해야함./// ❌ 기존 코드 var responseHeader: [String: String] = [:]for (hea..

UNUserNotificationCenter `requestAuthorization`에서 발생하는 희귀한 버그 현상 분석

UNUserNotificationCenter `requestAuthorization`에서 발생하는 희귀한 버그 현상 분석 사내에 2021년에 작성된 코드에서 앱이 멈추는 상황이 발생해서 사례 분석앱 시작 직후가 아닌, 사용자에게 별도 페이지에서 안내 후 버튼 클릭을 통한 권한 요청의 동선 상세한 분석 링크https://github.com/lgvv/unusernotificationcenter-requestauthorization-blocking-simulation GitHub - lgvv/unusernotificationcenter-requestauthorization-blocking-simulation: Investigating Rare Bugs in UNUserNotificationCeInvestiga..

l-value, r-value

l-value, r-value 프로젝트 내 C, C++, objective-c, swift 코드가 존재하여 이를 분석하면서 개념 정리. 용어 정리 L-value (locator value)란? 메모리상의 위치(location) 를 가리키는 표현식.: 대입의 왼쪽에 올 수 있는 것(항상은 아님). 변수, 배열 원소, 프로퍼티, deref(*p) 등. : 즉, 여기에 값을 저장할 수 있음. R-value (right value)란?실제 값(리터럴, 계산 결과, 일시적인 임시객체). : 보통 대입의 오른쪽에 오는 것. 임시값이므로 주소를 갖지 않거나 곧 사라짐. : 즉, 이건 읽을 수는 있지만, 직접 이곳에 값을 저장할 수는 없다. 참고현대 언어는 이분법을 확장.- 예: C++의 xvalue/prvalue/g..

Actor에서 Class + OSAllocatedUnfairLock

Actor에서 Class + OSAllocatedUnfairLock 상태 보호를 위해서 actor로 작성된 객체를 class + OSAllocatedUnfairLock으로 변경함. 변경하게 된 계기는 고빈도 호출 코드에서 고성능이 보장되어야 하는 영역을 프로파일링하는 과정에서 특정 메서드의 호출 빈도가 높아지는 경우 지속적으로 CPU Usage가 높게 잡히는 부분이 있어서 확인 Actor 기반으로 작성한 메서드를 실행했을 때 completeTaskWithClosure로 나타나는 영역에서 Weight를 많이 차지함. 해당 메서드의 구현부는 swiftlang / swift에 존재. https://github.com/swiftlang/swift/blob/main/stdlib/public/Concurrency..

Swift Concurrency Task weak self 실험 정리

Swift Concurrency Task weak self 실험 정리 Task에서 weak self 사용과 관련해서 실험들을 정리.개념에 대한 부분을 따로 생략함. Swift에서 Task를 사용할 때 self를 강하게 캡처하지만, 클로저가 종료될 때 메모리 Swift의 Task는 기본적으로 self를 강하게 캡처하기 때문에, Task의 수명이 self보다 길어질 경우 retain cycle 없이도 self의 deinit 호출이 지연될 수 있음.따라서 Task가 더 오래 살아 있을 가능성이 있다면 [weak self]를 명시하는 것이 안전.반면, Task의 수명이 self보다 짧고 일회성 작업에 그친다면 굳이 [weak self]를 사용할 필요는 없음. 목차example_1Task에 weak self를 명..

Tuist CocoaPod 연동

Tuist CocoaPod 연동 Tuist에서 CocoaPod을 연동하고자 함. 폴더 구조루트 폴더에서 아래와 같은 형태로 Podfile을 생성함.Dailytodo/├── Podfile ✅├── Tuist.swift├── Workspace.swift├── Projects/└── Dailytodo.xcworkspace Podfile 작성프로젝트 구조에 따라 cocoapod 의존성이 필요한 부분에 모두 작성해줌. ```platform :ios, '16.0'use_frameworks!inhibit_all_warnings!workspace 'Dailytodo.xcworkspace'project 'Projects/App/Dailytodo/Dailytodo.xcodeproj'project 'Projects/Co..