2018년 4월 27일
Kotlin/Native v0.7의 출시를 기쁘게 알려드립니다! 이번 릴리스는 Objective-C 및 Swift와의 상호 운용성을 더욱 원활하게 지원하며, 메모리 관리 개선, 전역 프로그램 분석 및 성능 최적화를 제공합니다. 또한 이번 릴리스에서는 많은 버그 수정과 최적화도 포함되었습니다.
AppCode와 CLion Kotlin/Native 플러그인도 v0.7과 함께 업데이트되었으며, 이에 따라 성능 및 사용성이 약간 개선되었습니다.
바이너리는 다음 링크에서 다운로드할 수 있습니다: macOS, Linux, Windows
또한 Linux Snap 패키지도 사용 가능합니다.
GitHub 릴리스 페이지는 여기에서 확인하실 수 있습니다.
더 원활한 상호 운용성
다음과 같은 Kotlin 측 코드를 상상해보십시오. 이 코드는 프레임워크로 컴파일되어 Swift에서 사용됩니다.
fun isItTimeForKotlin(date: NSDate): String {
val kotlin10Release = NSISO8601DateFormatter().dateFromString(
"2016-02-15T00:00:00Z")!!
return if (date.timeIntervalSinceDate(kotlin10Release) >= 0) "sure!" else "yes"
}
이전에는 Swift 세계에서 오는 객체로 timeIntervalSinceDate()와 같은 Objective-C API를 호출하는 것이 불가능했습니다. 이제 다음과 같이 호출할 수 있습니다.
let now = Date()
print(Common.isItTimeForKotlin(date: now))
또 다른 인기있는 요청은 Swift와 Kotlin 세계 간에 객체를 투명하게 변환하는 기능입니다. 즉, 이제 다음과 같이 할 수 있습니다.
val string = "Kotlin" as NSString
val list = listOf(1, "Konan") as NSArray
val map = mapOf(1 to "one", 2 to "two") as NSDictionary
또는 역방향으로, Objective-C NSDictionary를 Kotlin으로 변환하는 것도 가능합니다.
val data = ("{ \"foo\": 1} " as NSString).dataUsingEncoding(NSUTF8StringEncoding)!!
val jsonObject = NSJSONSerialization.JSONObjectWithData(
data, 0, null) as? Map<Any?, *> ?: throw Error("JSON parsing error")
println(jsonObject["foo"])
그런 다음 일반적인 Kotlin 맵처럼 사용할 수 있습니다.
UI를 생성할 때는 초기화 메서드 오버라이드를 사용하는 것이 일반적이지만 Kotlin의 생성자는 가상이 아닙니다. 다음 스니펫은 도움이 될 것입니다.
@ExportObjCClass
class ViewController : UIViewController {
@OverrideInit constructor(coder: NSCoder) : super(coder)
@ObjCOutlet lateinit var button: UIButton
@ObjCAction fun buttonPressed() {
println("Hello!")
}
}
NSCoder를 허용하는 생성자는 @OverrideInit로 표시되며 가상으로 호출됩니다. 다른 좋은 기능으로는 Objective-C/Swift 측에서 Kotlin에서 발생시킨 체크 예외와의 상호 운용성을 지원하는 것입니다(Kotlin 메서드가 @Throws 주석으로 표시된 경우).
메모리 모델 개선: 불변 객체, 약한 참조
Kotlin/Native는 공유 데이터를 가능한 한 피하려고 노력해왔습니다. 그러나 특정 시나리오에서는 일부 공유 불변 데이터가 필요할 수 있습니다. 일반적인 예로는 시작 시 파일에서 읽은 설정 데이터이며 이후 어디에서든 사용할 수 있도록 제공됩니다. 이러한 목표를 달성하기 위해 객체 불변화 개념을 구현했습니다. 객체는 가변 상태이며 단일 스레드나 워커에 의해 소유될 수 있거나 불변 상태이며 여러 스레드나 워커 사이에서 공유될 수 있으며 모든 소비자가 더 이상 필요하지 않을 때 해제될 수 있습니다.
data class Config(val root: String, val version: Int)
fun init() {
val config = Config("/path", 1).freeze()
val workers = Array(10, { _ -> startWorker()})
// Pass all workers a config.
workers.forEach { it -> it.schedule(TransferMode.CHECKED, { config } ) {
config -> println("got $config hash is ${config.hashCode()}")
}}
}
이 코드는 불변 인스턴스를 생성하고 10개의 워커에게 전달하여 모두 동일한 구성 인스턴스를 공유합니다. 불변 객체는 동시에 사이클 안전한 참조 카운터 기반 메모리 관리의 장점을 가지며, 불변 객체는 참조 카운터에 기반하여 DAG로 변환되므로 참조 카운터만으로도 수집할 수 있습니다. 불변 객체를 변이하려고 하면 런타임 예외가 발생합니다. 따라서 불변화는 여러 스레드나 워커 간 객체를 더 안전하게 공유할 수 있도록 합니다. Kotlin/Native의 동시성 접근 방법에 대한 자세한 내용은 이 문서를 참조하십시오.
다른 요청된 기능으로는 약한 참조, Objective-C 객체에 대한 약한 참조도 포함됩니다. 약한 참조는 특정 객체가 더 이상 필요하지 않고 메모리 관리자에 의해 할당 해제된 경우를 알 수 있도록 합니다. 이를 통해 캐시와 같은 데이터 구조를 구현하거나 Objective-C 세계와 상호 운용할 때 참조 사이클을 끊을 수 있습니다.
class Ref : NSObject() {
var ref: WeakReference<NSObject> = WeakReference(this)
}
fun update(ref: Ref) = autoreleasepool {
ref.ref = WeakReference(Ref())
}
fun test() {
val x = Ref()
println(x.ref.get()) // Gives reference to x.
update(x)
println(x.ref.get()) // Gives null.
}
성능 최적화: 가상 메서드 제거, 박스 캐싱
Kotlin/Native의 성능 접근 방식은 가능한 한 많은 미리 최적화를 수행하는 것입니다(대조적으로 JVM 접근 방식은 대부분 최적화를 실행 시간에 수행합니다). 이러한 최적화의 주요 요소는 해결된 다형성을 갖는 전역 호출 그래프를 구축하는 것입니다(즉, 변수의 실제 런타임 타입을 계산하며, 이는 시그니처에 명시적으로 나와 있거나 프론트엔드에서 추론한 타입이 아닙니다). 이것은 모든 구성 요소가 최종 코드 생성 중에 알려지는 폐쇄된 세계 컴파일에서 가능합니다. Kotlin/Native는 호출 그래프 및 교차 모듈 유형 전파를 기반으로 가상화 분석을 수행합니다. 이는 미래에 아레나 기반 메모리 할당기에 대한 피난처 분석과 같은 추가 최적화를 허용할 것입니다.
인기 있는 기본 타입에 대한 상자 값은 컴파일 중에 캐시되며 실행 시간에 할당되지 않으므로 메모리 관리 오버헤드를 줄일 수 있습니다.
원문
'Kotlin > Release Notes' 카테고리의 다른 글
[Kotlin Release Notes] Kotlin 1.2.50 is out! (0) | 2023.09.05 |
---|---|
[Kotlin Release Notes] Embedding Kotlin Playground (0) | 2023.09.05 |
[Kotlin Release Notes] Kotlin 1.2.40 is out! (0) | 2023.09.05 |
[Kotlin Release Notes] Kotlin/Native Plugin for AppCode (0) | 2023.09.05 |
[Kotlin Release Notes] Kotlin 1.2.30 is out (0) | 2023.09.05 |
댓글