小编bro*_*oot的帖子

定制容器视图控制器

我想创建自己的容器视图控制器,即UINavigationController或类似的东西UITabBarController.文件说我不应该这样做,但为什么不呢?导航和tabbar容器是很好的例子,这样的东西是可能的,并且工作得非常好.另外我知道iPhone有小屏幕,人们不应该通过导航按钮等弄乱它,但是在iPad上有很多空间,将它分成许多视图控制器会给我们很大的机会.

我有一种感觉Apple还没有添加这样的API,但他们会.几天前,他们已经添加了关于iPad专用控制器的文档(是的,容器控制器),并且他们将文本修改为不那么令人生畏的东西.

无论如何......如果我尝试在一个屏幕上使用两个或更多视图控制器,我可能遇到什么问题?我知道只有其中一个会获得方向更改或低内存警告等事件,因此我必须将这些事件传递给包含的VC.我担心与未来版本的iOS的兼容性,因为如果他们将添加新事件,那么包含的VC将不会执行从中继承的默认操作UIViewController.还要别的吗?你认为我的应用程序可能会被Apple拒绝吗?也许还有其他方法可以在每个屏幕上保留一些视图元素,而无需将大量相同的代码复制到每个VC中?

提前致谢.

iphone uiviewcontroller ipad ios

6
推荐指数
1
解决办法
6253
查看次数

在 Kotlin 中创建子协程范围

短(-ish)故事

我想知道是否有或多或少的标准方法来创建协程上下文/范围,以便:

  • 它是用于结构化并发的当前协程的子项,
  • 它可以存储在某些属性等中,然后用于运行异步任务,例如launch()

coroutineScope()正是我所需要的,它创建了一个子作用域,但它不是简单地将它返回给调用者——我们需要传递一个 lambda 并且协程生命周期仅限于这个 lambda 的执行。另一方面,CoroutineScope()工厂创建了一个长时间运行的作用域,我可以存储以备后用,但它与当前的协程无关。

我能够手动创建这样的范围:

suspend fun createChildCoroutineScope(): CoroutineScope {
    val ctx = coroutineContext
    return CoroutineScope(ctx + Job(ctx.job))
}
Run Code Online (Sandbox Code Playgroud)

乍一看,它似乎完全符合我的需要。它相当于什么coroutineScope(),或者我的解决方案在某种程度上不完整,我应该执行一些额外的任务?我试图阅读 的源代码coroutineScope(),但它相当复杂。是否有更简单或更标准的方法来创建子作用域?

此外,它是否被认为是一种不好的做法或反模式?我只是担心如果已经没有这样一个简单的函数,那么可能是有原因的,我不应该真正以这种方式使用协程。

用例(更长的故事)

通常,当我实现某种可以异步安排后台操作的长时间运行的服务时,我会看到这种需求:

class MyService {
    fun scheduleSomeTask() {
        // start task in the background
        // return immediately
    }
}
Run Code Online (Sandbox Code Playgroud)

使用协程有几种可能性:

  1. GlobalScope,但很糟糕。

  2. scheduleSomeTask()使用当前协程使可挂起并运行后台任务。在许多情况下,我认为这种方法并不是真正合适的方法:

    • 后台任务由调用者“拥有”,而不是由服务本身“拥有”。例如,如果我们停止服务,后台任务将仍在运行。
    • 它要求调度功能是可挂起的。我认为这是错误的,因为我真的不明白为什么不允许某些 Java 代码或协程上下文之外的代码在我的服务中安排任务的原因。
  3. 给我的服务定义的生命周期,创建范围与CoroutineScope()cancel()它停止/销毁时。这很好,但我认为我们仍然可以从协程的结构化并发中受益,所以对我来说,我的服务分离是一个缺点。

    例如,我们有一个文件下载服务,它由(拥有)其他服务组成,包括数据缓存服务。使用start()/stop()服务的典型方法,我们需要手动控制生命周期,并且很难正确处理故障。协程让它变得更容易:如果缓存服务崩溃,它会自动传播到下载服务;如果下载服务需要停止,它只是取消它的协程,它可以确保它不会泄漏它的任何子组件。所以对我来说,在设计由几个小服务组成的应用程序时,协程的结构化并发可能非常有用。

我目前的方法是这样的:

class MyService {
    private lateinit …
Run Code Online (Sandbox Code Playgroud)

kotlin kotlin-coroutines

6
推荐指数
1
解决办法
408
查看次数

在 Kotlin 中仅向具有多个类型参数的扩展函数提供一个类型参数

介绍

在 Kotlin 中,我有一个通用转换扩展函数,它可以简化从一种this类型的对象C到另一种类型的对象T(声明为receiver)的转换,并提供额外的转换action,该转换视为receiver原始this对象并提供对原始对象的访问:

inline fun <C, T, R> C.convertTo(receiver: T, action: T.(C) -> R) = receiver.apply {
    action(this@convertTo)
}
Run Code Online (Sandbox Code Playgroud)

它的使用方式如下:

val source: Source = Source()
val result = source.convertTo(Result()) {
    resultValue = it.sourceValue
    // and so on...
}
Run Code Online (Sandbox Code Playgroud)

我注意到我经常在由无参数构造函数创建的函数上使用这个函数,并且认为通过创建基于其类型自动构建receivers的附加版本来进一步简化它会很好,如下所示:convertTo()receiver

inline fun <reified T, C, R> C.convertTo(action: T.(C) -> R) = with(T::class.constructors.first().call()) {
    convertTo(this, action) // calling the first version of convertTo() …
Run Code Online (Sandbox Code Playgroud)

generics default-constructor type-constraints kotlin extension-function

5
推荐指数
1
解决办法
1116
查看次数