V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
xiubin
V2EX  ›  程序员

iOS 开发中,把一个比较大的控制器(ViewController)通过继承来把视图布局和事件分开,这样好不好?

  •  
  •   xiubin ·
    wxiubin · 2017-07-05 16:49:16 +08:00 · 4620 次点击
    这是一个创建于 2486 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在项目中经常会碰见一个比较大点的 ViewController,子视图可能比较多,而且会处理子视图的各种代理事件,vc 中还要处理逻辑,网络、数据等。

    所以,我对于这种情况的解决办法一般是:

    1. 写一个基类,里面初始化各种子视图,并且约束布局。
    2. 继承基类,数据、事件、逻辑等处理

    这样看着是很舒服、很清晰了,但是否违反继承的初衷?

    27 条回复    2017-07-06 16:26:09 +08:00
    googlebot
        1
    googlebot  
       2017-07-05 17:25:01 +08:00 via Android
    apple 的思路是搞 delegate,不需要继承,你可以定义自己的 delegate,

    cocoa 的系统架构比 ms 水平高多了,windows 都是 api,com,cocoa 是各种 delegate,
    zetasq
        2
    zetasq  
       2017-07-05 17:37:10 +08:00
    如果你这个 UI 其他地方也要用到,但是每处的数据和逻辑不一样,那么写一个基类比较方便(比如 UITableViewController) 。如果只有一个地方用到,基类感觉没啥用(初始化代码太多的话,可以尝试在每个 subview 的 initializer 里分担逻辑)。不过一般业务代码 viewcontroller 的文件都会比较大,做好 mark 就好了
    zengyuxi
        3
    zengyuxi  
       2017-07-05 17:42:01 +08:00
    MVVM (非 RAC )

    如果会 RAC 的话,更好!
    HelveticaNeue
        4
    HelveticaNeue  
       2017-07-05 18:05:16 +08:00
    个人不喜欢这种继承。
    分层、分模块的本质是为了高效地复用代码。如果不存在复用代码的需求,为什么要拆开布局和业务?我觉得这种分层反而增加了复杂度。用 MARK 分好段落就可以了。
    allenzyq1314
        5
    allenzyq1314  
       2017-07-05 18:11:31 +08:00
    反正无论什么都有 1 2 个 baseviewcontroller。 就怕以后加业务逻辑会写太多多余代码。。
    GTim
        6
    GTim  
       2017-07-05 18:13:50 +08:00
    swift 的话 extension 值得拥有
    ma125125t
        7
    ma125125t  
       2017-07-05 18:16:47 +08:00
    子视图当做 viewcontroller 来做,作为主视图的 child viewcontroller,这样就不违背 MVC,也能精简代码了呀。
    xi_lin
        8
    xi_lin  
       2017-07-05 18:20:30 +08:00
    你的场景要的是 subViewController 吧
    其实 category 也行
    a412739861
        9
    a412739861  
       2017-07-05 18:21:57 +08:00
    和 ls 相似,感觉应该用 child ViewController,child ViewController 也能复用。
    LINAICAI
        10
    LINAICAI  
       2017-07-05 18:31:41 +08:00
    永远不要让视图去处理网络数据,你要做的是拿到数据后把数据扔给视图然后刷新视图
    GaoMjun
        11
    GaoMjun  
       2017-07-05 18:55:21 +08:00 via Android
    viewcontroller 几千行正常
    Durandcol
        12
    Durandcol  
       2017-07-05 19:01:24 +08:00
    1.在需要复用的前提下 再对之前的代码做分层
    2.不要执拗于 MVC MVVM 本质上只是放代码的地方, 只是方便程序员维护与理解 搞了一层抽象的东西.
    3.继承不要搞太多层.
    xiubin
        13
    xiubin  
    OP
       2017-07-05 21:52:38 +08:00
    @googlebot #1 继承和 delegate 没直接关系吧?继承是为了复用和扩展,delegate 是事件 /数据回调和分发才用的吧?

    @zetasq #2 我也是这么想的,可能最近重构公司项目看多了 2、3k 行的控制器烦了,想把所有的控制器代码减到 3、4 百行(也只是想想~)。我说的这个控制器的子视图其实有 self-manager 的概念,该控制器的直接子视图并不负责渲染和显示,而是又管理了一大堆的视图,说是 View,其实承载的是 Controller 的功能。

    @ma125125t #7
    @xi_lin #8
    @a412739861 #9
    是的,我上面的回复也有提到,这个控制器的直接子视图是 Controller 的作用,其实用 child ViewControlle 是最好的
    34D
        14
    34D  
       2017-07-05 22:23:50 +08:00
    category
    jesse_luo
        15
    jesse_luo  
       2017-07-06 00:54:15 +08:00
    1. 减少继承,增加组合
    2. 没人说 view delegate 一定要用 VC 处理吧
    3. View 不要自己处理业务逻辑
    googlebot
        16
    googlebot  
       2017-07-06 07:08:15 +08:00 via iPad
    继承是非常差的架构,代码非常难维护,代码分离太差,
    出了问题你都不知道在第几层出的问题,
    akring
        17
    akring  
       2017-07-06 07:35:49 +08:00 via iPhone
    @xiubin 摸爬滚打这么些年,2,3k 的真不算什么…见过 10k+的
    free9fw
        18
    free9fw  
       2017-07-06 09:15:56 +08:00
    swift extension+RxSwift
    JasperYanky
        19
    JasperYanky  
       2017-07-06 09:25:13 +08:00
    1.可以试试 ViewModel
    2.可以试试 Category
    ma125125t
        20
    ma125125t  
       2017-07-06 09:46:57 +08:00
    @akring 2,3k 在 iOS 算挺多的了
    cheng4741
        21
    cheng4741  
       2017-07-06 09:50:06 +08:00
    不到万不得已别用继承,楼上说过的 extension,viewmodel 都是很好的方案,还可以另外写一个类处理一些逻辑,然后组合到 vc 中,各种 delegate 可以交给这个类去处理
    holy_sin
        22
    holy_sin  
       2017-07-06 09:52:41 +08:00
    rx.fuckEverything, you need it
    blacklee
        23
    blacklee  
       2017-07-06 09:56:02 +08:00
    用 category 是一个很不错的解决方案,一个实例(左边是.m 文件的代码行数)

    cdLI
        24
    cdLI  
       2017-07-06 09:59:18 +08:00   ❤️ 1
    推荐一篇文章:https://www.raywenderlich.com/132662/mvc-in-ios-a-modern-approach, 用此类方式,我目前在公司做的项目 viewController 里的代码没有超过 300 行的
    blacklee
        25
    blacklee  
       2017-07-06 10:04:29 +08:00   ❤️ 1
    另外感觉其实代码多并不是非常的让人难受。
    还是应该在命名、组织上面多下点功夫。比如前些年有一个思潮是「我们不写注释,因为我们的代码已经足够易读易解」。不过这个层次还是很难达到,我练习了几年,仍然感觉功力不够。
    M80
        26
    M80  
       2017-07-06 10:13:27 +08:00
    纯吐槽:category 的方案不就是等于把垃圾扫到沙发底下,然后装作房间已经整洁了么?
    这么说的原因是,即使分割成了多个 category,各个实现上都有可能存在互相依赖。
    如果简单的 ViewController 可以做的事情是:做 ViewModel,提取 UITableView/UICollectionView 的 Adapter,上下文无关的地方,提取 Util 等等一些朴实的方法。
    而复杂后,可以推荐使用 http://clean-swift.com/ 里这种类 VIPER 的做法。
    (其实说到底还是经验和练习不够
    sfz97308
        27
    sfz97308  
       2017-07-06 16:26:09 +08:00
    不倾向于用继承和 Category。可以根据实际情况,拆成 Child View Controller,或者加一层 ViewModel
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   973 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 21:16 · PVG 05:16 · LAX 14:16 · JFK 17:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.