Vladimir Berezkin
Vladimir Berezkin

Reputation: 3599

Does kotlin-native have destructors?

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?

Upvotes: 13

Views: 7187

Answers (2)

Werner Altewischer
Werner Altewischer

Reputation: 10464

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

Upvotes: 0

Nikolay Igotti
Nikolay Igotti

Reputation: 598

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") 
   }
}

Upvotes: 18

Related Questions