2020의 게시물 표시

[swift] swift 기본 문법 스터디 7주차

이미지
[swift] swift 기본 문법 스터디 7주차 일급 객체로서의 함수 특성 런타임에서 생성가능 인자값으로 객체 전달가능 반환값으로 객체를 사용할 수 있어야 함 변수, 데이터 구조 안에 저장 고유한 구별이 가능 변수나 상수에 함수를 대입할 수 있음 함수의 결과값을 변수나, 상수에 대입하는 것이 아는 그 자체를 변수나 상수에 대입할 수 있습니다. func printAddFive(base: Int) -> String { return "결과 값은 \(base)입니다." } let fnc1 = printAddFive(base: 4) // 결과 값은 9입니다. 위의 예제는 함수를 선언하고, 그 함수의 결과값을 변수에 저장하는 예제 입니다. let fnc2 = printAddFive fun2(5) // 결과 값은 10입니다. 이렇게 함수 자체를 대입하고, 인자를 넣어서 호출 할 수 있습니다. 하지만 왜 _ 이렇게 라벨을 없애지 않았는데 없어진 걸까요? 변수를 대입하는데에 타입이 필요하고, 같은 타입에 연산이 가능 하듯이 함수도 마찬가지 입니다. 함수도 함수 타입이 있습니다. (인자타입1, 인자타입2) -> 반환타입 우리가 위에서 만든 printAddFive 함수의 타입을 적어보면, (Int) -> String 이 되겠군요. 함수의 반환타입으로 함수를 사용할 수 있음 함수의 반환에는 자료형이나, 클래스, 구조체 뿐만 아니라 함수도 반환할 수 있습니다. 그러면 어떻게 생겼을까요? func desc() -> String { return "desc 함수입니다." } func pass() -> () -> String { return desc } let p = pass() p() // desc 함수입니다. 위의 예제 코드를 보면, pass 함수는, () -> String 이라는 함수를 반환 합니다. 그리고 그

[Xcode] Breakpoint를 이용한 디버깅 툴 응용

이미지
[Xcode] Breakpoint를 이용한 디버깅 툴 응용 문제를 해결하기 위해서는 디버깅을 해야하는데, 좋은 디버깅 도구가 있음에도 프린트 문을 쓰거나 po 명령어만 쓰고 있는 자신을 발견하여, 좀 더 좋은 도구의 사용법을 익히고자 정리 해 둡니다. signal SIGABRT break point 프로그래밍을 하다 보면, 어디서 왜 죽었는지도 알기 전에 Thread 1: signal SIGABRT 빨간 라벨이 나와서 매우 분노한 일이 많았습니다. 이럴 때 어디서 죽는 건지 브레이크 포인트도 걸 수 없는데 어떻게 해야할까요? 브레이크 포인터 네비게이터로 간 후, 왼쪽 하단에 Exception Breakpoint를 누른 후 아무 곳이나 클릭 한 후 다시 실행 시켜 줍니다. 이번에는 Exception이 발생한 지점에서 멈춰있는 것을 알 수 있습니다. 브레이크 포인트를 걸지도 않았는데 말이죠. 그 다음은 브레이크 포인트가 걸려있는 지점을 살펴 보아야겠죠? 브레이크 포인트로 로그 남기기 원하는 곳에 브레이크 포인트를 걸고 값을 출력 해 본 적있으신가요? 예를 들면, 스크롤뷰에서 화면내 이미지의 마지막 순간 값을 출력 해 보려고 했던 경험 저는 많은데요. 스크롤 할 때마다 계속 브레이크 포인트에서 걸려 매우 난감했던 순간이었습니다. 이럴 때는 원하는 곳에 브레이크 포인트르 지정하고, 브레이크 포인트를 우클릭 합니다. edit breakpoint 를 누르면 이름과 조건을 설정할 수 있습니다. 하지만 우리가 필요한 기능은 Action이 Debbuger Command 입력란에 우리가 항상 브레이크 포인트가 걸리면, 입력해주는 lldb 명령어를 입력해줍니다. 예를 들면, po self.contentsOffset 과 같이 말입니다. 그리고 Automatically continue…를 체크 해주면, 이제 멈추지 않고 커맨드창에 출력됩니다. 더 나아가서, Action에 값을 Debbuger Command이 아닌 Log M

[iOS] GCD와 Operation Queue

이미지
[iOS] GCD와 Operation Queue GCD를 공부하던 중 정리가 잘 되지 않아 정리 해 보려고 합니다. 그리고 같이 공부할 키워드로 떠오른 Operation Queue와는 어떤점이 다른지 정리 하려고 합니다. GCD(Grand Central Dispatch)는 멀티 코어 하드웨어에서 코드 동시 실행을 지원합니다. 코드의 동시실행을 이해하려면, 실행의 단위를 잘 알아야 합니다. 코드를 작성하면, 어떠한 기능을 하는 파일이 됩니다. 이를 프로그램 이라고 합니다. 이 프로그램은 운영체제의 메모리에 올라가며, 프로그램의 인스턴스를 생성합니다. 이를 프로세스 라고 합니다. 프로세스는 운영체제로 부터 독립된 자원을 할당 받습니다. 그리고 그 프로세스에서 여러가지의 일을 실행하는 단위를 쓰레드 라고 합니다. 쓰레드는 프로세스가 할당 받은 자원 중 독립적으로 스택만 새로 할당 받고, 나머지 자원들은 쓰레드끼리 공유합니다. 정래 해보면 코드로 프로그램을 실행하고, 그 프로그램이 하나 실행되면 하나의 프로세스가 생성됩니다. 그리고 그 프로세스 안에서 흐름의 단위가 쓰레드 입니다. 멀티 프로세스 와 멀티 쓰레드 이름으로 부터 의미를 유추 해 보도록 하겠습니다. 멀티 프로세스란 하나의 프로그램 안에 어려가의 프로세스가 동작할 수 있도록 하는 것 이겠군요. 그렇다면 하나의 프로그램 안에서 각각의 독립적인 자원을 할당받은 프로세스들이 기능을 할테니, 프로세스끼리 영향을 주지 않아 독립적으로 사용할 수 있어서 좋겠습니다. 하지만 반대로 공유하는 자원이 없어서, 데이터를 전송하고 받아야겠네요. 멀티 쓰레드란 하나의 프로세스에서 여러개의 쓰레드를 사용하는 방법 일 것 입니다. 멀티 프로세싱의 방법과 반대로, 공유하는 자원이 있으며, 데이터를 전달하는 방법이 간단할 것 같습니다. 하지만 공유하는 자원이 있따는 것은 잘 못 관리하면 의도하지 않았던 데이터의 왜곡이 일어나서 버그를 만들기 쉽겠습니다. 동시성 과

[UXKit] 앱 탐구 생활 - Share the meal

이미지
[app review] 앱 살펴보기 - Share the meal App store best of the 2020 앱 중 하나로 선정된 ShareTheMeal 을 살펴 보았습니다. 앱의 구조 4개의 탭으로 이루어진 앱 입니다. 각각의 탭 메뉴를 선택 했을 때는 아이콘의 색이 변하면서 화면 전환이 일어납니다. 크게 복잡하거나 화려하지 않은 심플한 구조 입니다. 기부하다 페이지 카드 스와이핑 페이지 입니다. 비슷한 라이브러리는 SwipingCarousel 라는 것이 닮아 보였습니다. 꽉찬 화면이 아닌, 이쁜 테두리로, 굉장히 아름다워 보입니다. 미묘하게 가운데 카드는 크고 양 옆 카드들은 크기가 작아지는 것도 재미있네요. 꼭 한번 구현 해 보겠습니다! 와이파이의 환경에서는 메인 이미지를 썸네일로 한 동영상이 자동 재생됩니다. 연결된 네트워크를 탐지해서, 동영상을 컨트롤 하는 방법에 대해서도 정리 해 보도록하겠습니다. 상세 페이지로 들어가면, 이미지와 프로그레스바, 그리고 내용들이 나옵니다. 하단에는 후원하기 버튼이 있고요. 이미지 갤러리의 경우에는 콜렉션 뷰로 되어있고 하단의 콜렉션뷰와 연동되어 클릭하면, 해당 이미지가 나옵니다. 애플지도를 쓰는 것도 처음봐서 신기했습니다. 복사는 웹페이지의 링크가 되고, 누르면 해당 앱으로 떨어집니다. 바로 앱으로 떨어지는 다이나믹링크를 쓰면 좋았을 것 같네요. 기부 등록 이 페이지는 정기 후원을 위한 페이지로, 콜렉션 뷰로 설명을 해주고 후원하기 버튼을 누르면 후원 페이지로 이동합니다. 후원 페이지는 카드를 스와이핑 하면서 메뉴를 고를 수 있는 페이지 입니다. 커뮤니티 그룹을 만들거나 참여할 수 있습니다. 마찬가지로 컬렉션 뷰로 추천팀을 고를 수 있으며, 이 탭은 상단에 또 작은 탭바가 한 번 더 들어가 있습니다. 탭바는 클릭 했을 때 부드럽게 그림자가 이동하는 걸 볼 수 있었습니다. 프로필 나의 정보가 나오고, 정기

[dev] 구글의 코드 리뷰

이미지
[dev] 구글의 코드 리뷰 기술 블로그에 약간 지침을 느끼고, 하나씩 배운 것들을 정리하고자 최근에 읽었던 글 중 기억에 남는 부분 위주로 번역하겠습니다. Code Reviews at Google are lightweight and fast 라는 글 입니다. 구글에서 코드리뷰는 엔지니어의 중요한 역할 중 하나 입니다. 엔지니어들은 코드를 깔끔하게 관리하고자 하기 때문이죠. 마이크로 소프트의 코드리뷰와 비슷할 수 있으나, 구글만의 특징이 있습니다. 그래서 구글에서의 코드리뷰 방법을 소개하도록 하겠습니다. Code Review Study at Google study to understand Google’s internal code review processes 논문에 기술한 방법으로 코드리뷰를 합니다. Preparing code for review 코드를 수정하면 마크가 생기고, 변경사항이 머지되고 나면 코드리뷰가 시작됩니다. 구글은 내부 코드리뷰 도구인 Critique 로 변경사항을 먼저 체크합니다. 코드리뷰를 보내기 전에는 정적 분석도구를 통해 코드를 실행합니다. 내부에서 사용되는, Tricorder를 실행하고 결과를 검토합니. 그리고 최소 한명 이상의 리뷰자를 선정해 리뷰를 요청합니다. Reviewers give feedback 리뷰어는 코드를 살펴보고 문제가 있거나 설명이 필요한 경우 코멘트를 남깁니다. 그 다음 요청자는 코멘트를 회신하여 코멘트를 처리합니다. 코드가 수정되었을 경우에는 새 버젼을 올려 변경사항을 확인할 수 있게 합니다. 리뷰어가 만족하면 LGTM(Look good to me) 를 표시하여 승인 합니다. Code Reviews at Google 모든 변경된 코드는 리뷰 되어야 합니다. 75% 이상의 코드는 한명의 리뷰어가 승인했습니다. 승인한 리뷰어 또한 코드에 오너쉽을 가지며, 가독성에 대한 보장을 해야합니다. 작은 리뷰는 1시간 이내에, 커도 4시간 안에는 리

[swift] swift 기본 문법 스터디 6주차

이미지
[swift] swift 기본 문법 스터디 6주차 함수 함수란 입력값을 받아 처리하여 반환 하는 형태를 띈 코드의 덩어리를 의미합니다. 여러번 반복되서 작성된 코드를 함수의 호출로 처리할 수 있습니다. 연속적으로 작성하는 것 보다 기능별, 목적별로 나누어 코드의 가독성이 올라갑니다. 수정이 필요할 때 함수 내부만 수정하면되니 유지, 보수에 유리 합니다. 함수의 반환값 함수는 인자 옆에 -> 기호와 함께 반환 값의 타입을 입력해줍니다. return 키워드와 함께 반환해줍니다. 반환값이 없는 경우에도 return 키워드를 입력해서 함수의 종료를 명시적으로 표현해 줄 수 있습니다. 하나의 값만 반환하지만, 컬렉션 타입에 여러개의 값을 담아 한 덩어리로 묶어서 반환하는 방법도 있습니다. 함수의 호출 함수를 호출 할 떄는 이름과 인자를 넘겨주어 호출할 수 있습니다. 레이블이 있다는 것이 스위프트의 독특한 문법 중 하나입니다. 내부 매개변수명, 외부 매개변수명 외부에서 호출될 때와 내부에서 매개변수를 사용할 때 다른이름을 쓸 수 있습니다. _ 를 이용하여 외부 매개변수를 사용하지 않을 수 도 있습니다. 변수의 범위 변수는 영향을 줄 수 있는 범위를 가지고 있습니다. 기본적으로 블록 내부에서 선언된 변수는 블록이 종료되면 사라집니다. 또한 변수를 만나면 어디서 선언되었는지 검색합니다. 함수 내부에서 찾음 함수 외부에서 찾음 글로벌에서 찾음 외루 라이브러리에서 찾음

[swift] swift 기본 문법 스터디 5주차

이미지
[swift] swift 기본 문법 스터디 5주차 옵셔널 옵셔널은 스위프트에서 도입된 새로운 개념입니다! 값이 없음을 의미하는 nil의 개념은 다른언어에도 존재하는데요, 값이 없을 수도있다는 nil이 될 수 있다는 타입을 옵셔널 이라고 합니다. 에러를 내는 것 보다는 무언가 문제가 있다, 혹은 해당 연산에 대한 결과 값은 없다라는 의미로 사용되어 에럴 없이 코드가 동작하게 도와주는 녀석입니다. Optional(“값”) 으로 감싸줍니다. 만약 감싼 값이 없다면? 그렇죠 nil이 들어있겠죠! 이렇게 Optional에 Wrapping 되어있는 옵셔널 타입의 값은 Unwrapping 해서 사용해야 하죠. 그럼 정의부터 하나씩 살펴볼까요 옵셔널의 선언 type+? 입니다. 예를 들어 var age: Int? 이런식이죠. 옵셔널인지 아닌지는 nil을 대입해보면 됩니다. 여기서 추가적으로, Int 와 Int?는 다른 타입이므로 연산이 불가합니다. Unwrapping해서 사용해야 하지요. Optional Unwrapping 옵셔널안에 있는 값을 꺼내오는 방법은 어러가지가 있지만, 그 중에 가장 쉬운 방법은 ! 연산자를 사용한 강제 추출 방법이 있습니다. age! 와 같은 방법으로 값을 꺼낼 수 있습니다. 문제는 age안에 nil이 들어있을 때 앱이 죽을 수 있으니 조심해서 사용해야 합니다. Optional Binding을 사용하면, 안전하게 값을 꺼내올 수 있습니다. 내가 필요한 값은 꺼내오고 없으면, 실행하지 않습니다. if let, guard let 과 같은 방법으로 언래핑 할 수 있습니다. 비교할 때에는 컴파일러 단에서 자동으로 값을 꺼내오기도 합니다. 옵셔널의 묵시적 해제 옵셔널 타입이긴 하지만, 값을 사용할 때는 자동으로 옵셔널 타입이 해제되는 방법입니다. var name: String! = "Leeo" 이렇게 사용합니다. 형식상 옵셔널로 정의해야 하지만, 실제로는

TokenMemo 앱을 배포하고 난 후

이미지
TokenMemo 간단하게 터치 한번으로 메모 내용을 복사할 수 있습니다. 메모를 추가하고, 그 내용을 입력하면됩니다. 클립보드에 내용이 있다면, 자동으로 추가 할지를 물어봅니다.

[swift] swift 기본 문법 스터디 4주차

이미지
[swift] swift 기본 문법 스터디 4주차 집단 자료 (collective Types) 관련있는 데이터 끼리 모아서 관리 할 수 있는 자료형입니다. 같은 형태의 여러개의 자료를 다룰 때 유용하게 쓸 수 있습니다. Array Set Tuple Dictionary Array 데이터에 index로 접근할 수 있습니다 순서가 있어서 계속 인덱스가 늘어납니다 하지만 중간에 데이터가 사라지면 앞으로 당겨집니다 반복 반복을 하는 방법이 다양합니다. 처음부터 끝까지 반복됩니다. 초기화 초기화 하는 방법에는 다양한 방법이 있습니다. 선언 : var name: [String] 초기화 : name = [String]() 동적할당 append - 맨뒤에 추가됩니다 insert(at) - 해당 인덱스 자리에 추가 후 나머지는 1씩 뒤로 밀립니다 append(contentsOf) - 여러개의 인자를 추가됩니다 범위 연산자 할당 당하는 영역보다 할당하는 영역이 크면 -> 길이가 늘어납니다 반대는 길이가 줄어듭니다 Set 중복이 없으며, 순서에 대한 보장도 없습니다. 대신 해시연산의 결과 값을 이용하여, 저장하기 때문에 불러올 때 성능이 매우 빠릅니다. 정의 Set () 추가는 .insert 로 할 수 있습니다. 순회가 가능합니다. 집합연산이 가능합니다. Array와 Set을 비교해서 사용처를 구분하는게 좋지 않을까요? 여부판단 말고 어떤 예제가 있을까요? Tuple 특별한 성격 집단의 자료형으로, 여러 타입의 데이터를 한번에 담을 수 있습니다. 하지만, 최초에 선언된 상태의 아이템만 사용하고, 수정삭제 추가 불가능 하다는 것이 특징입니다. () 을 사용하여 정의합니다. Dictionary 키와 밸류가 연결되어있는 자료형입니다. 배열과 같은 어노테이션을 사용하며, 같은 타입만 들어갈 수 있습니다. 값을 업데이트 할 수 있습니다. 또한 순회하면서 탐색할 수

[UXKit] 앱 탐구 생활 - 29CM

이미지
[app review] 앱 살펴보기 (1) - 29CM 에디터 추천 이 붙어있는 앱을 한번 살펴볼까 합니다. 29CM이라는 앱이고, 디자인적으로 굉장히 잘 되어있다고 해서 선정하게 되었습니다. 앱 구성 크게 5개의 탭바로 되어있습니다. 깔끔한 아이콘과 복잡하지 않은 탭바 아이콘 설명이 깔끔한 느낌을 줍니다. 가운데는 영상을 위한 페이지이며, 탭바의 색이 반전되어 있습니다. 다른 화면이지만 나머지 화면들과 디자인 적으로 같아보였습니다. 디자인에 무지해서인지, 화면 전반에 존재하는 왼쪽의 여백에 눈이 많이 갔습니다. 어떤 미적 의미가 있는지 아시는 분은 댓글로 알려주세요. 메인의 투명한 네비게이션바와 우측의 하얀색버튼이 눈에 걸리지 않게 색변화 하는 점이 매우 신기 했습니다. 또한 속도에 따른 네비게이션 버튼과 탭바의 등장과 사라짐은 신기한 경험이었습니다. 따라 구성해보고 싶은 부분 화면이 움직이는 속도에 따라 반응하는 컴포넌트 들 텍스트라벨 부터 탭바, 네비게이션까지 사용자가 빠르게 스크롤 할 때와 느리게 할떄가 반응이 달랐습니다. 화면을 아래로 스크롤링 했을 때 탭바가 올라오고, 위로 스크롤링 했을 때 탭바가 내려가는 기능 29TV에 있는 공유하기 버튼 귀욤뽀작하게 SNS버튼으로 구성된 커스텀 공유 버튼을 구현해보고 싶습니다. 이미지 배너를 스크롤링 할 때 자연스럼게 백그라운드 컬러로 fade out 빠른 스크롤링에도 끊김없는 카드로딩과 스크롤링

[swift] swift 기본 문법 스터디 3주차

이미지
[swift] swift 기본 문법 스터디 3주차 이번주는 흐름제어에 대해 정리해 놓으려고 합니다. 가장 정확한 문서는 공식문서라고 생각하고, 링크 를 첨부해 놓겠습니다. 불면증을 위해 한 번 정독했습니다. 반복문 for ~ in 루프상수, 순회대상 루프상수의 생략가능 다중루프 -> 차원을 줄이는 것이 가능? 몇번 돌지 보통은 알지 않을까요? while 조건을 만족하는 동안 실행 한번은 실행을 보장해주는 repeat while 어떻게 만들어 진걸까요? Dictionary Array set 범위데이터 문자열 Sequence Iterator 조건문 if if 키워드 뒤에는 반드시 조건식이 와야합니다. 참 일 경우에는 if 뒤의 구문을 실행합니다. 중첩된 이프문의 조건 정리하는 꿀 팁 아시는 분? guard 조기 종료 참일 때 실행되는 구문이 없다 조건 체크에 사용하면 좋습니다 #available(<플랫폼이름 버전>, <플랫폼이름 버전>, <플랫폼이름 버전>…) switch 일치하는 패턴이 있다면 실행하고 switch문 종료 default 패턴 매칭 제어 전달문 break switch에서 사용, 반복문에서 사용 종료 continue 종료하지 않고 패스! label 신기! fallthrough 다음으로 넘어가지 않음! return 함수와 메소드에서 사용 값을 반환, 종료

[swift] swift 기본 문법 스터디 2주차

이미지
[swift] swift 기본 문법 스터디 2주차 변수와 상수 메모리에 값을 저장하려면 저장하고 싶은 메모리의 주소값이 필요합니다. 그리고 우리가 저장한 값을 가져올 때도 메모리의 주소값이 필요하겠죠? var x: Int = 10 print(x) withUnsafeMutablePointer(to: &x) { print("x address: \($0)") } x = 20 print(x) withUnsafeMutablePointer(to: &x) { print("x address: \($0)") } let y: Int = 30 print(y) withUnsafePointer(to: &y) { // error! print("y address: \($0)") } 위와 같은 방법으로 메모리 주소값을 찍어보았습니다. 생각보다 간단하지 않아 당황했네요. 그런데 아직 의문인것은 같은 변수이지만, let 변수는 mutable 하지 않기 때문에 withUnsafeMutablePointer로 주소를 찍을 수 없었습니다. 이 부분에 대해서는 어떤 의미가 있는지 더 찾아보고 수정하도록 하겠습니다. 또한 변수에는 한글, 알파벳, 아라비아숫자, 특수기호까지 지원하는데 영어와숫자를 사용하는 것 이외에 다른 방법으로 변수를 할당하는 예가 있다면 알려주세요! 자료형 우리가 저장한 변수에는 타입이 있습니다. 기본적으로는 같은 타임의 변수들끼리 연산이 가능하죠. 실제 자료형들은 구조체로 구현되어 있으며, 연산이 가능한 연사자들이 내부에 정의 되어 있습니다. Int - 정수를 저장할 때 씁니다. signed Int8 => 127 ~ -128 : 2^8(256) Int16 => 32767 ~ -32768 : 2^16(65,536) Int32 ^^;; Int64 ^^;; unsigned Int8 => 0 ~

[swift] 옵셔널 체이닝 vs 옵셔널 바인딩

이미지
[swift]옵셔널 체이닝 vs 옵셔널 바인딩 옵셔널 체이닝과 옵셔널 바인딩이 헷갈려 정리해 놓았습니다. 언제 필요할까요? 옵셔널은 프로퍼티에 값이 있을 수도있고, 없을 수도 없음을 나타내는데 사용되었습니다. 옵셔널은 값이 없을 때 nil을 할당 해줍니다. 문제는 우리가 필요한 값이 nil인지 아닌지 확인을 해야하는 번거로움이 있다는 것 입니다. 코드로 예를 들어보겠습니다. class Person { var name: String var job: String? var home: Apartment? init(name: String, home: Apartment?) { self.name = name self.home = home } } class Apartment { var buildingNumber: String var roomNumber: String var security: Person? var owner: Person? init(dong: String, ho: String, security: Person?) { self.buildingNumber = dong self.roomNumber = ho self.security = security } } let chulsoo: Person? = Person(name: "chulsoo", home: apart) let apart: Apartment = Apartment(dong: "101", ho: "202", security: chulsoo) let hyunho: Person? = Person(name: "leeo", home: apart) leeo 라는 사람의 apart 에 있는 security의 이름이 알고 싶습니다.

[iOS] Prefetching으로 프레임드랍 막기

이미지
[iOS] Prefetching으로 프레임드랍 막기 필요한 이유 컬렉션 뷰에서 cellForRowAt 메소드로 데이터를 가져와서 컬렉션 뷰를 그릴 경우, 셀을 구성하는 작업은 메인 쓰레드에서 진행 될 것입니다. 많은 셀을 메인 쓰레드에서 진행한다면, 프레임 드랍이 일어날 수 있고 결과적으로 매끄러운 스크롤링이 불가능합니다. 이런 작업을 돕기 위해 Prefetching이 추가되었습니다. 사용 필요 요건은 다음과 같습니다. iOS 10.0+ Xcode 11.3+ 비교 그럼 그냥 컬렉션 뷰만 쓸 때와는 어떤점이 다를까요? 사실 이미지나, 서버에 요청해서 데이터를 받아오지 않아서인지 큰 차이를 느끼지 못했습니다. 하지만 구현 해놓고 브레이킹 포인트를 걸고, 출력을 해 보면서 차이를 느낄 수 있었습니다. 가장 먼저 제가 다름을 느낀 곳은 같은 화면을 구성하는데 프리패칭 프로토콜을 채택해서 구현 했느냐, 아니냐에 따라 데이터의 fetching 갯수가 다른 것 이었습니다. 왜냐하면 cellForRowAt에서는 셀을 그리기 위한 작업만을 해서 그런지 그리기 위한 데이터만 가져오는 것 처럼 보였습니다. 하지만 프리패칭 프로토콜을 채택하면, 디스플레이 영역이 아닌, 프리패칭의 영역의 데이터를 미리 가져옵니다. 그렇기 때문에 가져오는 데이터의 갯수가 다릅니다. 화면에 6개가 그려져야 할 때, Prefetching 없이 컬렉션 뷰로 그리게 되면 일단 화면에 그려지는 6개의 셀의 데이터만 가져오고 아래로 스크롤 할 때 새로운 데이터를 로드 합니다. 하지만 이 갯수가 중요한게 아닙니다. 이 그림을 그리는 작업이 어디서 이루어지고 있는지가 핵심입니다. 셀을 그리고 있는 cellForRowAt작업은 메인 스레드에서 이루어지는데 해야 할 일들이 많아지면 다 처리하지 못하고 프레임 드랍이 일어날 수 있다. 이 작업 중 일부가 백그라운드에서 일어나게 되면 메인 쓰레드에 걸리는 부하가 줄어들고 프레임 드랍

IOS Developer Roadmap

IOS Developer Roadmap IOS개발로드맵 을 보고 공부 순서대로 진행하면서 느끼는 회고를 정리하려 합니다. 최근 업데이트일 : 2020-11-13 개발자의 기본역량 자료구조와 알고리즘 기본적인 터미널 사용법 깃과 버젼관리 [2020-04-14] git을 사용하는데 필요한 기본 개념과 기본 용어 정리 [2020-09-09] git의 upstream과 origin 헷갈리는 사람 손! [2020-09-09] git의 마지막 커밋 메시지 수정하기 SSH HTTP / HTTPs 그리고 API 정보 검색 [2020-04-11] 구글링 할 때의 팁 문자열과 인코딩 오픈소스 [2020-04-01] 오픈소스 라이선스 정리 [2020-04-11] Github 이슈 라벨(issue labels) [2020-04-21] Opensource에 처음 기여해보고 싶어서 찾은 내용 [2020-05-06] 오픈소스 기행문 - 문서번역 (만화로보는 https 동작원리) [2020-09-29] Kingfisher 둘러보기 [2020-10-27] Hacktober Fest 참가하세요 두 번 하세요! 기초체력 Swift 기본문법 Collections ControlFlow(while, for, iterating collection, nested loop) [2020-09-17] if 문에서 콤마와 && 연산자의 차이점 Optional [2020-03-27] Optional값 다루기 [2020-10-21] Optional 뜯어보기 Optional binding [2020-03-25] guard let, if let 차이 Guard [2020-10-06] guard문으로 함수 입구 틀어막기! Object Oriented Programing [2020-03-27] 함수(fuction)의 기본 개념정리 [2020-03-28] 구조체(struct

[swift] guard let, if let 차이

이미지
[swift] guard let, if let 차이 Optional 변수를 안전사게 사용하기 위해 방법을 찾던 중 if let과 guard let에 대해 정리하겠습니다. 변수에 값이 올지 않올지 확신할 수 없을 때 Optional을 씁니다. 그러면 Optional 타입의 변수에 값은 어떻게 꺼내어 사용할 수 있을까요? 간단합니다 옵셔널 바인딩을 해서 사용합니다. 값이 올지 안올지 정확히 알 수 없을 때 Optional 타입의 변수 를 사용하는데요 잘 모르는 분들이 이 전 글을 참고 해주세요! 안전하게 Optional 타입의 변수를 Unwrap하기 위해서는 옵셔널 바인딩을 해야하는데요 크게 두 두가지 방법이 있습니다. 바로 if let과 gurad let 입니다. 코드로 보는 예제 다음 예제 코드를 통해 둘의 차이점을 살펴 보겠습니다. func fullName(name:String, rawPrefix:String?){ // if let을 사용했을 경우 if let prefix = rawPrefix { print(prefix+name) } else { print("need prefix") } // guard let을 사용했을 경우 guard let prefix = rawPrefix else { print("need prefix") return } print(prefix+name) } fullName(name: "hyunho", rawPrefix: "Lee") 풀네임을 작성할 때 이름은 필수이지만 성은 언제나 들어오지는 않는 옵션널 한 값 입니다. guard let을 사용하는 경우에 이름만 들어오고 성이 들어오지 않았다면, 이런 케이스는 예외 케이스, 혹은 원하지 않는 상황 이라고 판단합니

[iOS] ViewController의 화면전환 방법 정리

이미지
[iOS] 화면전환 방법 어떤 버튼을 눌러 다른 페이지로 이동 시키는 일은 항상 헷갈립니다. 이번 기회에 정리해 두고 가려고 합니다. 일단 버튼을 하나 만들고 눌러서 내가 원하는 페에지와 실제 페이지가 잘 나타나는지 정리하겠습니다. 이런 버튼이 하나 있고 화면을 전환 해 보도록 하겠습니다. 스토리 보드 가장 쉬운 방법이라고 생각합니다. 내가 액션을 줄 컴포넌트를 클릭하고 컨트롤 + 드래그로 원하는 페이지에 드롭합니다. 선이 생기면서 어떻게 보여줄 것인지 segue action을 선택하면 됩니다. 일단은 present modally를 선택합니다. 버튼을 누르면 모달 창이 새로 생기죠? 아주 쉽고 간편하답니다! viewController present @IBAction func buttonClick(_ sender: Any) { let viewControllerName = self.storyboard?.instantiateViewController(withIdentifier: "SecondViewID") if let view = viewControllerName { self.present(view, animated: true, completion: nil) } } 다음과 같은 코드를 작성해줍니다. 스토리 보드에 만들어 준, 뷰컨트롤러의 스토리보드 아이디를 설정 해줍니다. 저는 SecondViewID 로 설정 해주었습니다. 버튼에 IBAction을 설정 해 준다음에 스토리 보드에서 스토리 보드에서 설정했던 ID를 가지고 옵니다. 그리고 가져온 뷰컨트롤러를 self에서 present 해줍니다. viewControllerName?.modalTransitionStyle를 설정하여 모달의 전환을 설정할 수 있습니다. @IBAction func buttonClick(_ sender: Any) { let viewController

[dev] Hacktober Fest 2020 참가하세요 두 번 하세요!

이미지
[dev] Hacktober Fest 참가하세요 두 번 하세요! 올 해 초부터 오픈소스에 관심을 가지고, 저도 모두를 위한 오픈소스에 컨트리뷰터가 되고자 이런 저런 노력을 했었습니다. 결과는 대 참패… 물론 어떻게 오픈소스를 시작하는지도 공부했고, 첫 커밋을 어떻게 하면 좋을지에 대해서도 공부했었습니다. 하지만 결국 기여하고자 하는 오픈소스를 열어보았을 때 으악! 하고 덮어 버린 것… 이번에는 올 해 엿보고 있던 핵토버 페스트에 참가 해 보았습니다. 무엇을 해야하는지 몰라서 웹페이지 에 들어가서 소개글과 이벤트 들을 읽어 보았습니다. 그 중에 PR을 4번 날리면 티셔츠를 주는 이벤트에 참가 하기로 했습니다. 규칙은 간단했습니다. hacktoberfest2020에 참가하는 레파지토리에 PR을 4번 이상 날린다. 유예기간인 14일 이 지날 때 까지 내가 날린 PR에 Reject 이 없거나 Accept 이 있으면 됩니다. 총 4개의 최종 카운팅이 완료되면 보상을 받을 수 있습니다. 시작 그 와중에도 어떻게 하면 좋을지 찾아보다가 이런 필터 를 사용해서 기여할 만한 프로젝트를 찾았습니다. 저는 초보자 이기 때문에 good first issue 와 swift 로 제한을 두고 찾았습니다. 매너? 기여 했던 프로젝트 중 참고할 만한 내용이 있어서 공유 합니다. 이슈 창에 들어가보면 현재 문제라고 제기 된 이슈들이 있고, 담당자가 없는 곳에가서 참가 의사를 밝혀달라고 합니다. 만약 다른사람이 이미 진행하고 있는 이슈라면 해당 레파지토리에 가서 기여해달라는 내용이 있습니다. 이렇듯 오픈소스에서도 지켜야 하는 예의가 있었습니다. 몰랐었는데 다른 것도 있는지 찾아봐야겠네요. 일합니다 할 수 있는 이슈에 가서 자신에게 할당해달라고 합니다. 그러면 프로젝트 메인테이너?인지 어떤 분이 오셔서 흔쾌히 할당을 해줍니다. 당연히 저는 처음이라 잘 모르니 어떻게 하는지 고민할 시간에 다시 물어봅니다.

[swift] Optional 뜯어보기

이미지
[swift] Optional 뜯어보기 swift에서 데이터를 저장하는 곳을 변수라고 하는데, 이 변수에 아무것도 들어있지 않은 상태를 표현해야 할 일이 있습니다. 0이 아니고 빈 문자열("")도 아닌 아무것도 없는 것. 변수에 아무것도 할당 되어있지 않은 것을 스위프트에서는 참을 수 없으니까요! 아무것도 들어있지 않다라는 것이라도 넣어 둡시다. 이때 사용되는 것이, 없다 라는 오브젝트인 nil입니다. 변수에 아무 값도 들어있지 않다는 뜻 입니다. 사용 법 정의 타입 뒤에 ?를 붙여주면 옵셔널타입 이라는 뜻 입니다. var name: String? = "leeo" print(name!) // leeo name = nil print(name!) // error 이렇게 사용가능합니다. 조금 더 자세히 살펴보면 var name: String? = "leeo" 이 코드에서 타입이 String?임을 알 수 있습니다. 정확히는 이런 뜻 입니다. var name: Optional<String> 왜냐하면 typealias String? = Optional<String> var name: String? 이렇게 한 것과 같은 의미기 때문이죠. 그렇다면 Optional 을 까보고 똑같이 구현해 보도록 하겠습니다. public enum CustomOptional<Wrapped>: ExpressibleByNilLiteral { case none case some(Wrapped) public init(nilLiteral: ()) { self = .none } public init(_ some: Wrapped) { self = .some(some) } } extension CustomOptional: CustomDebugStringConvertible { public var debugD