Function references, garbage collection, leaking context?


#1

I have something like this:

abstract class Preferences {
    val prefs: SharedPreferences
    internal val ctx: Context

    constructor(context: Context) {
        ctx = context
        prefs = PreferenceManager.getDefaultSharedPreferences(context)
    }

    inner abstract class Preference<T>(val key: String, val default: T) : ReadWriteProperty<Any?, T> {
        constructor(resId: Int, default: T) : this(ctx.getString(resId), default)
    }

    // Omitted: the non-abstract subclasses of Preference
    // They're not really relevant here
}

The problem with this implementation is that it stores a reference to the context, so it’s possible to leak contexts if I pass around a Preferences object. I’d like to avoid this if possible.

Will storing only the function reference context::toString allow the rest of the context to be thrown out? Like this:

class Preferences {
    val prefs: SharedPreferences
    internal val getString: (Int) -> String

    constructor(context: Context) {
        getString = context::getString
        prefs = PreferenceManager.getDefaultSharedPreferences(context)
    }

    inner abstract class Preference<T>(val key: String, val default: T) : ReadWriteProperty<Any?, T> {
        constructor(resId: Int, default: T) : this(getString(resId), default)
    }
}

#2

context::getString will hold a pointer to the context internally, so it won’t be thrown out while this function pointer is alive.