静态类型语言中的生命周期方法

时间:2016-09-04 21:41:51

标签: android ios swift functional-programming kotlin

去年,我成为了移动开发人员和功能性编程崇拜者。

在每个移动领域,都有一些组件具有生命周期方法,构成了应用程序的核心。以下将使用Android和Kotlin作为示例,但同样适用于iOS和Swift。

在Android中,有Activity个生命周期方法,如onCreate()。您还可以定义一个函数onButtonClicked(),它将完全按照名称描述。

出于问题的目的,让我们说onCreate()中定义的变量用于按钮点击处理程序onButtonClickedPrintMessageLength()这通常是案例 - onCreate()基本上是Activity的设置方法)。

示例类看起来像这样:

class ExampleActivity: Activity() {
    var savedStateMessage: String? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        savedStateMessage = "Hello World!"
    }

    fun onButtonClickedPrintMessageLength() {
        System.out.println(savedStateMessage?.length)
    }
}

注意savedStateMessage声明为String?(可空字符串)并使用?.(空安全呼叫)。这些是必需的,因为编译器无法保证在onCreate()之前调用onButtonClickedPrintMessageLength()。不过,作为开发人员,we know that onCreate will always be called first * **

我的问题是如何告诉编译器这些方法的保证顺序并消除空检查行为?

*我认为可以new向上ExampleActivity并直接调用onButtonClickedPrintMessageLength(),从而避开Android框架和生命周期方法,但编译器/ JVM很可能在发生任何有趣的事情之前遇到错误。

**首先调用onCreate的保证是由Android框架提供的,这是一个外部的事实来源,将来可能会以不同的方式破坏/运行。虽然看到所有Android应用程序都基于这一事实来源,但我相信它是值得信赖的。

3 个答案:

答案 0 :(得分:6)

虽然这不能回答您的实际问题,但在Kotlin中,您可以使用lateinit告诉编译器您将在以后初始化var

lateinit var savedStateMessage: String

如果在初始化之前尝试使用此变量,则会得到非常具体的UninitializedPropertyAccessException。此功能在JUnit等用例中非常有用,您通常会在@Before - 带注释的方法和Android Activity中初始化变量,在这种情况下,您无权访问构造函数并初始化内容。 onCreate()

答案 1 :(得分:1)

如另一个答案中所述,lateinit可用作将选项推迟到保证生命周期中的后续点。另一种方法是使用代理:

var savedStateMessage: String by Delegates.notNull()

这是等效的,因为如果在初始化之前访问变量,它将报告错误。

答案 2 :(得分:0)

在Swift中,您可以使用隐式解包的Optional

class Example: CustomStringConvertible {
  var savedStateMessage: String! // implicitly-unwrapped Optional<String>
  var description: String { return savedStateMessage }
  init() {
    savedStateMessage = "Hello World!"
  }
}

print(Example()) // => "Hello World!\n"

通过在示例第二行的!末尾使用运算符String,您承诺在使用变量之前将设置该变量。这是在示例的init方法中完成的。它仍然是Optional,但代码可以将其视为String,因为它会在每次使用前自动解包。您必须注意,当可能访问该变量时,该变量永远不会设置为nil,或者可能会生成运行时异常。