목록Book (47)
시배's Android
CoroutineContext는 원소나 원소들의 집합을 나타내는 인터페이스입니다. Job, CoroutineName, CoroutineDispatcher와 같은 Element 객체들이 인덱싱된 집합이라는 점에서 맵이나 셋과 같은 컬렉션이랑 개념이 비슷합니다. CoroutineContext의 모든 원소가 CoroutineContext로 되어 있습니다. CoroutineName이나 Job은 CoroutineContext 인터페이스를 구현한 CoroutineContext.Element를 구현합니다. CoroutineContext는 컬렉션과 비슷하기 때문에 get을 이용해 유일한 키를 가진 원소를 찾을 수 있습니다. 다른 키를 가진 두 원소를 더하면 만들어진 컨텍스트는 두 가지 키를 모두 가집니다. Corout..
중단 함수는 컨티뉴에이션 객체를 다른 중단 함수로 전달해야 합니다. 중단 함수가 일반 함수를 호출하는 것은 가능하지만, 일반 함수가 중단 함수를 호출하는 것은 불가능합니다. 중단 함수를 연속으로 호출하면 시작되는 지점이 반드시 있습니다. 코루틴 빌더가 그역할을 합니다. CoroutineScope 인터페이스는 부모 코루틴과 자식 코루틴 사이의 관계를 정립하기 위한 목적으로 사용되는 구조화된 동시성의 핵심입니다. runBlocking 빌더 코루틴이 스레드를 블로킹하지 않고 작업을 중단시키기만 하는 것이 일반적인 법칙입니다. 메인 함수의 경우 프로그램을 너무 빨리 끝내지 않기 위해 스레드를 블로킹해야 합니다. 프로그램이 끝나는 걸 방지하기 위해 스레드를 블로킹할 필요가 있는 메인 함수입니다. 스레드를 블로킹할..
코틀린 언어에서 자체적으로 지원하는 부분(컴파일러의 지원과 코틀린 기본 라이브러리 요소)과 코틀린 코루틴 라이브러리(kotlinx.coroutines)로 구성되어 있습니다. 언어 차원에서 지원하는 것과는 별개로 kotlinx.coroutines 라이브러리가 있습니다. 이 라이브러리를 사용하려면 프로젝트에 별도로 의존성을 추가해야 합니다. 언어 차원에서의 지원 kotlinx.coroutines 라이브러리 컴파일러가 지원하며 코틀린 기본 라이브러리에 포함되어 있다. 의존성을 별도로 추가해야 한다. kotlin.coroutines 패키지에 포함되어 있다. kotlinx.coroutines 패키지에 포함되어 있다. Continuation 또는 suspendCoroutines과 같은 몇몇 기본적인 것들과 susp..
중단 함수는 함수가 시작할 때와 중단 함수가 호출되었을 때 상태를 가진다는 점에서 상태 머신과 비슷합니다. 컨티뉴에이션 객체는 상태를 나타내는 숫자와 로컬 데이터를 가지고 있습니다. 함수의 컨티뉴에이션 객체가 이 함수를 부르는 다른 함수의 컨티뉴에이션 객체를 장삭합니다. 그 결과, 모든 컨티뉴에이션 객체는 실행을 재개하거나 재개된 함수를 완료할 때 사용되는 콜 스택으로 사용됩니다. Continuation Passing Style suspend fun getUser() : User? suspend fun setUser(user : User) fun getUser(continuation : Continuation) : Any? fun setUser(user : User, continuation : Cont..
중단 코루틴은 중단되었을 때 Continuation 객체를 반환합니다. Continuation을 이용하면 멈췄던 곳에서 다시 코루틴을 실행할 수 있습니다. 스레드는 저장이 불가능하고 멈추는 것만 가능합니다. 코루틴은 다른 스레드에서 시작할 수 있고, 컨티뉴에이션 객체는 (이론상) 직렬화와 역직렬화가 가능하며 다시 실행될 수 있습니다. 재개 중단 함수는 말 그대로 코루틴을 중단할 수 있는 함수입니다. 이는 중단 함수가 반드시 코루틴(또는 다른 중단 함수)에 의해 호출되어야 함을 의미합니다. ScheduledExecutorService를 통해 특정 시간 이후에 중단을 멈추고 재개할 수 있도록 할 수 있습니다. private val executor = Executors.newSingleThreadSchedu..
코틀린의 시퀀스는 List나 Set과 같은 컬렉션이랑 비슷한 개념이지만, 필요할 때마다 값을 하나씩 계산하는 지연 처리를 합니다. 요구되는 연산을 최소한으로 수행합니다. 무한정이 될 수 있습니다. 메모리 사용이 효율적입니다. val seq = sequence { yield(1) yield(2) yield(3) } fun main() { for (num in seq) { print(num) } } 인자는 수신 객체 지정 람다 함수입니다 (suspend SequenceScope() -> Unit) 람다 내부에서 수신 객체인 this는 SequenceScope를 가리킵니다. 중단을 지원하는 스레드로 처리하려면 유지하고 관리하는데 막대한 비용이 듭니다. val fibonacci : Sequence = sequ..
fun onCreate() { val new = getNewsFromApi() val sortedNews = news .sortedByDescending { it.publishedAt } view.showNews( sortedNews ) } 안드로이드에서는 하나의 앱에서 뷰를 다루는 스레드가 단 하나만 존재합니다. 이 스레드는 앱에서 가장 중요한 스레드라 블로킹되면 안 되기 때문에, 이런 방법으로 구현할 수 없습니다. 스레드 전환 : 블로킹이 가능한 스레드를 먼저 사용하고, 이후에 메인 스레드로 전환하면 된다. 스레드가 실행되었을 때 멈출 수 있는 방법이 없어 메모리 누수로 이어질 수 있습니다. 스레드를 많이 생성하면 비용이 많이 듭니다. 스레드를 자주 전환하면 복잡도를 증가시키며 관리하기도 어렵습니다...
개념 관점에서 설계는 도메인 안에 존재하는 개념과 개념들 사이의 관계를 표현한다. 도메인이란 사용자들이 관심을 가지고 있는 특정 분야나 주제를 말하며 소프트웨어는 도메인에 존재하는 문제를 해결하기 위해 개발된다. 명세 관점에 이르면 사용자의 영역인 도메인을 벗어나 개발자의 영역인 소프트웨어로 초점이 옮겨진다. 구현 관점은 프로그래머인 우리에게 가장 익숙한 관점으로, 실제 작업을 수행하는 코드와 연관돼 있다. 훌륭한 객체는 훌륭한 협력을 설계할 때만 얻을 수 있다. 협력을 설계할 때는 객체가 메시지를 선택하는 것이 아니라 메시지가 객체를 선택하게 해야 한다. 구현하지 않고 머릿속으로만 구상한 설계는 코드로 구현하는 단계에서 대부분 변경된다. 협력을 구상하는 단계에 너무 오랜 시간을 쏟지 말고 최대한 빨리 ..