做者:Antonio Leivahtml
时间:Mar 9, 2017android
原文连接:https://antonioleiva.com/property-delegation-kotlin/缓存
如咱们在前面文章中读到的,属性须要默认值,不能声明属性,而不给它们赋值。安全
因为你要存储视图到属性中,这就产生一个问题了。在对象建立期间,这赋值代码将被执行,而此时你不能访问这个内容。app
那你有能作什么?框架
属性委托将使用另外一个对象,这个对象可以调用get和set(若是使用了var)返回结果。ide
目前,咱们还不能控制许多对象的建立,如Android框架,在许多状况下,这委托将挽救咱们的生命。函数
我将向你展现三个例子,我认为它们在Android中很是有用。学习
对于这个例子,咱们用委托有两个选项,且禁止用null(若是你可以避免它,有些事情不建议使用)。ui
这是我最喜欢的,由于它迫使你对于不可变的、不太安全的属性使用var。
用保留字lateinit,说明属性不能为空,可是咱们仍然没有final价值:
1 lateinit var textView:TextView
在onCreate,咱们可以赋值给final值:
1 setContentView(R.layout.activity_main) 2 textView = findView(R.id.welcomeMessage) 3 toast(textView.text)
尽管它与委托notNull作相同的操做、被纳入第一喜欢,但这不是真正的委托。
第二个选择则更加优雅。它由Lazy委托组成,直至属性第一次被调用,相关代码是不会执行:
1 val textView by lazy { findView(R.id.welcomeMessage) }
在textView的get被第一次调用以前,findView是不能运行的。因为你不能错误的修改其值因此它更安全,而且它不会强制咱们在setContentView以后记得设置它。
此刻,咱们作:
1 toast(textView.text)
这行代码将在lazy形式下被执行。
如你所见,委托的方式用by保留字表示。
咱们来看另外一个例子。
在适配器中,咱们有items属性,每次自动启动adapter时更新。
1 var items: List by Delegates.observable(emptyList()) { 2 _, _, _ -> notifyDataSetChanged() 3 }
它简单地设置初始值,而后在每次更改后调用定义的函数。
在这种状况下,我只是调用notifyDataSetChanged,可是,如你所见,函数收到的新旧两个值,因此在技术上你能够检查变化是什么,只更新其区别。
若是你对这个例子有兴趣,我在另外一篇文章更普遍的描述它。
这是我发现的很是有用的另外一个情形。
返回到lazy,你可以在属性声明期间,用它声明应用的component:
1 val component: AppComponent by lazy { 2 DaggerAppComponent 3 .builder() 4 .appModule(AppModule(this)) 5 .build() 6 }
这个方法,你不须要用lateinit,属性则为不可变的。
若是在Activity中,用subcomponents,你可以作相同的事:
1 class HomeActivity : AppCompatActivity(), HomePresenter.View { 2 val component by lazy { app.component.plus(HomeModule(this)) } 3 ... 4 }
咱们已经见到怎样用委托是给咱们类属性的额外能力。而例如lazy,对变量也真的有帮助吗?Kotlin是缺少这一特性的。
如今,用局部委托属性,咱们作:
1 fun testLocalDelegation() { 2 val database by lazy { createDatabase() } 3 val cache by lazy { createMemoryCache() } 4 5 if (mustUseDatabase()) { 6 database.use { ... } 7 } else { 8 cache.use { ... } 9 } 10 }
尽管不使用lazy委托,这个例子可以解决,但它仍是有助于理解这些概念。
咱们有几个可能会或不会被使用的“笨重”对象。经过用lazy,咱们可以推迟它们的实例化,直到咱们确信要使用它们。
在首次使用时,花括号内的代码被执行,且被缓存起来,以备之后再使用。
属性委托将帮助你属性更强大,更简化,且代码可重用。
这里咱们仅仅看到Kotlin库的标准属性,而你可以建立你本身的属性。
例如在这本书中,我有实现从SharedPreference存储和取回数据。
若是你要学习更多这些内容,足够流畅建立本身的Android应用程序,我建议你获取这本免费指南,学习怎样建立你的第一个项目,或直接获取这本书,学习怎样从头开始建立一个完整的应用程序。