[회고] 신입 iOS 개발자가 되기까지 feat. 카카오 자세히보기

🍎 Apple 97

[Swift] Copy on write

Copy on write (COW) 이름 그대로 Write가 발생했을 때 Copy를 수행하는 기능입니다. (cf.이는 원래 운영체제에서 프로세스에게 프레임을 할당할 때 메모리 공간 낭비를 막기위해 사용되던 기능인데, Swift에도 비슷한 목적으로 적용되었습니다.) 값타입의 데이터는 값을 참조하지 않고 복사합니다. 하지만 이렇게 매번 복사를 할 경우 값이 변경될 필요가 없음에도 매번 새로운 메모리 공간을 할당하여 복사를 수행하게 됩니다. 따라서 메모리가 낭비되고, 오버헤드까지 발생합니다. 그래서 사용되는 것이 Copy on write입니다. Copy on write는 데이터 복사 시에 실제로 값을 복사하지 않고 동일한 값을 참조하도록 합니다. 그리고 값이 변경(Write)될 때 값을 복사해 변경을 적용합니..

🍎 Apple/Swift 2022.01.26

[Swift] 문자열 처리

코딩테스트의 주력 언어를 Swift로 변경하고나서 가장 번거롭게 느껴진 것은 문자열 처리였다. 문자열 처리가 쉬운 다른 언어와는 다르게 참 복잡하다고 생각했다. 하지만 그래도 정리하고 사용하다보면 금방 적응될 것이라고 생각한다. 그래서 개인적으로 번거로웠던 부분을 정리해놓는다. (새로운 팁을 알게되면 지속적으로 업데이트 예정) 문자열에 하나씩 접근하면 Character 타입으로 받아온다 파이썬은 for문을 활용해 접근했을 때 각 문자를 str형태로 받아온다. 하지만 Swift는 각 요소를 Character 타입으로 받아온다. let str = "Hello" for c in str { print("\(type(of: c)") } // Character // Character // Character // C..

🍎 Apple/Swift 2022.01.22

[Swift] NSCache와 NSDictionary의 차이점

NSCache 다짜고짜 차이점을 찾기 전에 NSCache가 뭔지부터 알아보자. NSCache는 메모리캐싱에 주로 사용되는 객체라고 알려져 있다. 리소스가 부족하면 자동으로 삭제되는 key-value 쌍을 임시로 저장하는 mutable collection 이라고 한다. 여기까지만 봐선 '자동으로 삭제되는' 이라는 부분이 Dictionary와 다른 점인데... 좀 더 알아보자. Overview를 보니 대놓고 차이점을 설명해주고 있다. 읽어보자. 먼저 시스템 메모리를 과도하게 사용하지 않도록하는 자동 삭제 정책을 가진다. 다른 애플리케이션에서 메모리를 필요로할 경우 이 policy가 cache에서 일부 항목을 제거한다. Thread-Safe하게 구현되어 있어 따로 lock하지 않아도 다른 스레드에서 캐시의 항..

🍎 Apple/Swift 2022.01.22

Clean Architecture and Design - Robert C. Martin (엉클 밥)

해당 게시글은 Robert C. Martin님의 Clean Architecture and Design 강의를 보고 내용을 정리한 게시글입니다. 다만 개인적인 정리 및 확인의 용도로 작성한 게시글이기 때문에 가독성이 떨어집니다. 관심 있는 분들은 직접 영상을 감상하시는 것을 추천드립니다. 한글자막도 있고 길이도 1시간 정도밖에 되지 않아요. 아직 안 보신 분은 꼭 보세요!!! https://amara.org/ko/videos/0AtjY87egE3m/url/1216370/ Video Subtitling, Captioning and Subtitle Translation - Amara Subtitling The FCCChairman's AAA The Chairman's Awards for Advancement ..

🍎 Apple/Patterns 2022.01.21

[iOS] 왜 오토 레이아웃을 사용할 때는 translatesAutoresizingMaskIntoConstraints = false를 할까?

왜 오토 레이아웃을 사용할 때는 translatesAutoresizingMaskIntoConstraints = false를 할까? 부모뷰가 커지거나 줄어듦에 따라 서브 뷰의 크기나 위치를 조정하는 방식을 결정하는 Autoresizing이라는 개념이 존재한다. 이 개념은 여러 속성을 부여하여 슈퍼뷰의 크기 변화에 따라 서브 뷰의 width, height 혹은 leading, top, trailing, bottom 영역을 유연하게 고정하거나 확장할 수 있다. 이러한 Autosizing은 AutoresizingMask를 통해 적용할 수 있는데, 슈퍼 뷰의 bounds가 변경 될 때 자신의 크기를 조정하는 방법을 결정하는 비트마스크이다. 다만 Autoresizing과 AutoLayout을 동시에 사용하고자 할 ..

🍎 Apple/Question 2022.01.21

[UIKit] Compositional Layout Example from Apple Sample Code (2)

1편에 이어서 작성! https://inuplace.tistory.com/1038 [UIKit] Compositional Layout Example from Apple Sample Code (1) Compostional Layout을 조금 더 잘 활용하고 싶어서 학습자료를 찾던 중 Apple Sample Code에서 너무 좋은 레퍼런스를 찾아서 이를 하나씩 정리해본 자료입니다. 🙃 https://developer.apple.com/documentation/ui.. inuplace.tistory.com Decorate Sections with Backgrounds let sectionBackgroundDecoration = NSCollectionLayoutDecorationItem.background( e..

🍎 Apple/UIKit 2022.01.18

[UIKit] Compositional Layout Example from Apple Sample Code (1)

Compostional Layout을 조금 더 잘 활용하고 싶어서 학습자료를 찾던 중 Apple Sample Code에서 너무 좋은 레퍼런스를 찾아서 이를 하나씩 정리해본 자료입니다. 🙃 Compositional Layout? Compositional Layout은 유연한 시각적 배열로 아이템들을 결합할 수 있는 레이아웃 객체이다. 이는 CollectionViewLayout의 한 타입인데, 작은 구성요소를 전체 레이아웃으로 결합하여 컨텐츠에 대한 시각적 배열을 구축할 수 있다. Compositional layout은 시각적으로 뚜렷한 그룹으로 나뉘는 하나 이상의 Section으로 구성된다. 각 Section은 표시하려는 가장 작은 데이터 단위인 Item으로 구성된다. Group은 항목을 수평, 수직 또는..

🍎 Apple/UIKit 2022.01.17

[iOS] 왜 UI는 메인 스레드에서 다룰까?

왜 UI는 메인 스레드에서 다룰까? 1. UIKit의 대부분 구성요소는 non-atomic하게 구성되어있는데, 이는 곧 Thread-safe하지 않다는 것을 의미한다. 모든 속성을 Thread-safe하게 설계하기엔 UIKit이 너무 방대한 프레임워크이다. 이를 억지로 보장하도록하는 것은 오히려 성능상으로 좋지 않다는 애플의 발표도 있다. 예를 들어 생각해보자. UITableView의 셀이 백그라운드 스레드에서 제거되었는데 다른 백그라운드 스레드가 해당 셀에 접근하려고하면 어떻게될까? 크래시가 발생할 것이다. 또 백그라운드 스레드의 Runloop에 특정 뷰에 대한 제거가 진행중에 있는데, 사용자가 해당 뷰를 탭하면 그 응답을 어떻게 처리해야할까? 어떤 스레드에서 해당 응답을 처리해야할지조차 애매하다. 2..

🍎 Apple/Question 2022.01.14

[Combine] share, multicast

share 하나의 upstream publisher의 output을 여러 subscriber들이 공유할 수 있도록 해준다. Example 1 guard let url = URL(string: "https://jsonplaceholder.typicode.com/posts") else { fatalError("Invalid URL") } let request = URLSession.shared.dataTaskPublisher(for: url).map(\.data).print().share() let subscription1 = request.sink(receiveCompletion: { _ in }, receiveValue: { print("Subscription 1") print($0) }) let sub..

[Combine] timer (by Runloop, Timer Class, DispatchQueue)

Combine을 통해 Timer를 생성하고 관리해보자. Runloop 입력소스 및 타이머 이벤트를 전달받는 인터페이스인 Runloop를 활용하여 Timer cacellable 객체를 생성할 수 있다. Runloop 공식문서에서 cacellable 객체를 생성하는 메서드를 확인할 수 있다. (마지막 schedule 메서드) Example let runLoop = RunLoop.main let subscription = runLoop.schedule(after: runLoop.now, interval: .seconds(2) , tolerance: .milliseconds(100)) { print("Timer fired") } runLoop.schedule(after: .init(Date(timeInterva..