Does kotlin-native have destructors?
Asked Answered
R

2

13

In kotlin native there is memScoped function that automatically free allocated memory when control is going out of scope. Is there something like destructors for local objects?

Rosales answered 25/6, 2017 at 15:33 Comment(0)
I
18

Current Kotlin/Native does not provide mechanism for calling a method when certain object is no longer needed in memory (finalizer in Java speech) but inline lambdas easily allow to implement mechanisms, similar to RAII in C++. For example, if you want to be sure, that some resource is always released after leaving certain scope, you may do:

class Resource {
  fun take() = println("took")
  fun free() = println("freed")
}

inline fun withResource(resource: Resource, body: () -> Unit) =
 try {
   resource.take()
   body()
 } finally {
   resource.free()
 }

fun main(args: Array<String>) {
   withResource(Resource()) { 
       println("body") 
   }
}
Iciness answered 26/6, 2017 at 7:45 Comment(3)
Is there a plan to add destructors at all? Or would you rather not because this kind of deterministic behavior is not possible to achieve anyway with Kotlin's other targets?Leeanneleeboard
There are no current plan to add general purpose destructors. However, somewhat similar functionality could be achieved with weak references, present in Kotlin/Native.Iciness
I was trying to have a similar functionality using WeakReference, as you mentioned, but still it doesn't seem to work, see youtrack.jetbrains.com/issue/KT-61830/… @NikolayIgottiForce
R
0

You could add an associated object to a Kotlin native object (via objc_setassociatedobject). Whenever the Kotlin object gets deallocated the associated object would as well. The dealloc method in that associated object could be used as a finalizer:

typedef void (^FinalizerBlock)(void);

@interface FinalizationMonitor: NSObject

- (instancetype)initWithTarget:(id)target finalizer:(FinalizerBlock)finalizer;

@end

@implementation FinalizationMonitor {
    FinalizerBlock _finalizer;
}

static char const *kFinalizerKey = "finalizer";

- (instancetype)initWithTarget:(id)target finalizer:(FinalizerBlock)finalizer {
    if ((self = [super init])) {
        _finalizer = finalizer;
        objc_setAssociatedObject(target, kFinalizerKey, self, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    return self;
}

- (void)dealloc {
    _finalizer();
}    

@end
val kotlinObject = ... // Some kotlin object
FinalizationMonitor(target = kotlinObject) {
   // Perform your finalization logic.
}

Of course this is a work around and not an ideal solution

Reek answered 27/4 at 7:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.