Swift通用继承 [英] Swift generic inheritance

查看:83
本文介绍了Swift通用继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个基本视图控制器和一些子视图控制器.我很难将在子级视图控制器(CommentViewController)中创建的视图模型传递给其父级视图控制器(FeedBaseViewController)进行访问.

I have one base view controller and some child view controllers. I am having difficulty to pass the view model created in children view controller (CommentViewController) to it's parent view controller (FeedBaseViewController) to access.

class BaseViewController: UIViewController {
    ...
}

class FeedBaseViewController: BaseViewController {
    var viewModel1 = FeedBaseViewModel<BaseObject>()
    ...
}

class CommentViewController: FeedBaseViewController {
    var viewModel2: CommentViewModel<CommentObject>

    init() {
        viewModel2 = CommentViewModel()

        /* This is where I have issue, and I tried a few approaches. And here are the 2 of them.*/
        // Method 1:
        // viewModel1 = viewModel2
        // Error: Cannot assign value of type 'CommentViewModel<CommentObject>' to type 'FeedBaseViewModel<BaseObject>'

        // Method 2:
        // viewModel1 = viewModel2 as FeedBaseViewModel<BaseObject>
        // Error: Cannot convert value of type 'CommentViewModel<CommentObject>' to type 'FeedBaseViewModel<BaseObject>' in coercion

        ...

    }
    ...
}

我的View Controller视图模型

My view models for the View Controller

class FeedBaseViewModel<Item: BaseObject> {
}

class CommentViewModel<T: CommentObject>: FeedBaseViewModel<CommentObject> {
}

这里是对象类,BaseObject类是这里唯一的Objective-C类,还有CommentBase swift类,它们是从BaseObject继承的.

Here are the object classes, the BaseObject class is the only Objective-C class here, and a CommentObject swift class which inherit from BaseObject.

@interface BaseObject : NSObject <NSCoding>
@end

class CommentObject: BaseObject {
}

我不确定是否可以这样做,或者只是语法问题. 请指教,谢谢!

I am not sure if it is possible to do, or it is only syntax issue. Please advice, thank you!

编辑(2017-09-11):

Edited(2017-09-11):

我想我可以提供我想要实现的更多信息,希望对您有所帮助.

I think I could provide more information of what I would like to achieve, and hope it helps.

FeedBaseViewModel存储和操作类型为BaseObject的项目数组. FeedBaseViewController具有UI处理操作,例如过滤",排序",并要求FeedBaseViewModel完成这项工作.

FeedBaseViewModel stores and manipulate an array of items with type BaseObject. FeedBaseViewController have UI handling actions such as "filtering", "sorting", and ask FeedBaseViewModel to do the job.

对于Comment部分,我将有一个CommentObject数组,其中包含基本操作和某些特定操作.这就是为什么CommentViewModel进入而CommentViewModel继承FeedBaseViewModel的原因,因此基本操作可以由父级处理,并且它将自己执行特定的操作.

For the Comment part, I will have a CommentObject array with basic manipulation and some specific manipulation. This is why CommentViewModel comes in, CommentViewModel inherit FeedBaseViewModel so that basic manipulation can be handled by the parent, and it will do the specific manipulation itself.

与视图控制器部分类似,CommentViewController将继承FeedBaseViewController,因此FeedBaseViewController可以进行基本处理,而CommentViewController本身可以提供其他功能.

Similar in the view controller part, CommentViewController will inherit FeedBaseViewController, so FeedBaseViewController can do the basic handling while CommentViewController itself can provide additional functions.

推荐答案

我认为这不可能.

您的问题归结为:

let m = FeedBaseViewModel<CommentObject>()
let k : FeedBaseViewModel<BaseObject> = m

那是不允许的.关于原因:假定FeedBaseViewModel包含其通用类型的成员,并为该成员提供set函数. 如果现在将允许您写第二行,则使用BasObject实例调用set,这将违反m的一般约束,因为它们仍然是相同的对象实例,但具有不同的对象通用约束,BaseObject实例不一定是CommentObject的实例.

That is not allowed. As to why: assume that FeedBaseViewModel contains a member of its generic type and offers a set function for that member. If you now would be allowed to write the second line, then call set using a BasObject instance that would violate the generic constraint of m because they are still the same object instance with different generic constraints, a BaseObject instance is not necessarily an instance of CommentObject.

您所需要的解决方案应该是将泛型再提高一点:

A solution in your case should be to move the generics up a little bit more:

class FeedBaseViewController<T : BaseObject>: BaseViewController {

    var viewModel1: FeedBaseViewModel<T>

    required init?(coder aDecoder: NSCoder) {
        viewModel1 = FeedBaseViewModel<T>()
        super.init(coder: aDecoder)
    }
}

class CommentViewController: FeedBaseViewController<CommentObject> {
    var viewModel2: CommentViewModel<CommentObject>

    required init?(coder aDecoder: NSCoder) {
        viewModel2 = CommentViewModel<CommentObject>()
        super.init(coder: aDecoder)
        viewModel1 = viewModel2 
        // now this assignment is allowed because viewModel1 and viewModel2 have the super type FeedBaseViewModel<CommentObject>
    }
}

不确定该解决方案是否适合您的情况.

Not sure if that solution works in your situation though.

这篇关于Swift通用继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆