【问题标题】:How to make an inline function remove itself when its being used as a listener in kotlin如何使内联函数在kotlin中用作侦听器时自行删除
【发布时间】:2021-09-23 21:11:30
【问题描述】:

我遇到了这个问题,我在 SO 中找不到任何问题的解决方案。

我正在使用来自Google's Paging libraryPagingAdapter 方法,它接收一个内联函数作为侦听器:

    fun addLoadStateListener(listener: (CombinedLoadStates) -> Unit) {
        differ.addLoadStateListener(listener)
    }

然后他们提供以下方法来移除监听器

    fun removeLoadStateListener(listener: (CombinedLoadStates) -> Unit) {
        differ.removeLoadStateListener(listener)
    }

我就是这样使用的

myPagingAdapter.addLoadStateListener { it: CombinedLoadStates -> 
    myPagingAdapter.removeLoadStateListener(this)
}

我知道上面的方法不起作用,但是当文件用 java 编写时它起作用了,因为它在自己的函数中有对自身的正确引用。但是,在 Kotlin 中,我根本找不到这样做的方法。我尝试变成一个匿名函数,但它仍然不会传递正确的上下文

myPagingAdapter.addLoadStateListener { fun(it: CombinedLoadStates) -> 
    myPagingAdapter.removeLoadStateListener(this)
}

此时我不知道如何删除无法引用自身的内联函数,而且我在任何地方都找不到任何具有解决方案的文档。

如何在 kotlin 中通过引用自身来删除内联函数?

【问题讨论】:

  • 不是内联函数。这是一个功能参考参数。内联函数是标记为inline 的函数,这意味着编译后的代码将其内容传输到调用站点,通常是为了启用具体泛型或避免为函数引用参数分配函数对象。参数永远不会内联,但如果它是内联函数的参数,则可以内联。

标签: android kotlin android-paging-library inline-functions android-paging-3


【解决方案1】:

如果我理解正确,您需要在addLoadStateListener 中传递的内联函数的引用,以便您可以在removeLoadStateListener 中传递。 你可以试试这个

myPagingAdapter.addLoadStateListener(object :  (String) -> Unit {
        override fun invoke(p1: String) {
            myPagingAdapter.removeLoadStateListener(this)
        }

    })

【讨论】:

  • 这听起来很有希望,并且看起来与 kotlin 中的非内联函数侦听器完全一样,可以满足我的需要。我稍后会对此进行测试,看看它是否适用于我的困境。
  • @Shadow 如果可行,请点赞并接受它(:
  • @Shadow 这些不是内联函数,这些是 lamda 函数。
  • 这个解决方案非常适合我的需要
  • 嘿@iamanbansal 你知道怎么解决这个问题吗issue
【解决方案2】:

你可以创建一个本地函数来引用自己:

fun myFun(CombinedLoadStates): Unit {
    myPagingAdapter.removeLoadStateListener(::myFun)
}

myPagingAdapter.addLoadStateListener(::myFun)

【讨论】:

  • 目标是让内联函数能够引用自身,以便在需要时将其删除。你的建议不能解决我的问题。如果我想在doThings() 中执行myPagingAdapter.removeLoadStateListener(myFun),它将无法正常工作。
  • 啊,在这种情况下你需要一个可引用的函数,见编辑。
  • 它不起作用。到执行删除调用时(任意时间),该函数的引用不再与添加时相同,除非我在进行添加侦听器调用的函数内声明该函数。我真正需要的是它引用自己的实例,否则它不能正常工作。
  • @Shadow 即使它不是本地函数,它似乎也能正常工作:pl.kotl.in/QHb3wczwJ 这个解决方案到底有什么问题?它确实在这里引用了自己。
  • @Joffrey 正确,您在其中实例化 fun myListenerFun 的实例将起作用的场景,问题是该实例不再相同,但仍然引用 val listeners。在您的示例中,它们都绑定到同一个实例,但在我的情况下,它们不是。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-28
  • 1970-01-01
  • 1970-01-01
  • 2015-05-23
  • 2017-11-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多