V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
xiubin
V2EX  ›  程序员

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

  •  
  •   xiubin ·
    wxiubin · Jul 5, 2017 · 5746 views
    This topic created in 3224 days ago, the information mentioned may be changed or developed.

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

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

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

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

    27 replies    2017-07-06 16:26:09 +08:00
    googlebot
        1
    googlebot  
       Jul 5, 2017 via Android
    apple 的思路是搞 delegate,不需要继承,你可以定义自己的 delegate,

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

    如果会 RAC 的话,更好!
    HelveticaNeue
        4
    HelveticaNeue  
       Jul 5, 2017
    个人不喜欢这种继承。
    分层、分模块的本质是为了高效地复用代码。如果不存在复用代码的需求,为什么要拆开布局和业务?我觉得这种分层反而增加了复杂度。用 MARK 分好段落就可以了。
    allenzyq1314
        5
    allenzyq1314  
       Jul 5, 2017
    反正无论什么都有 1 2 个 baseviewcontroller。 就怕以后加业务逻辑会写太多多余代码。。
    yemoluo
        6
    yemoluo  
       Jul 5, 2017
    swift 的话 extension 值得拥有
    ma125125t
        7
    ma125125t  
       Jul 5, 2017
    子视图当做 viewcontroller 来做,作为主视图的 child viewcontroller,这样就不违背 MVC,也能精简代码了呀。
    xi_lin
        8
    xi_lin  
       Jul 5, 2017
    你的场景要的是 subViewController 吧
    其实 category 也行
    a412739861
        9
    a412739861  
       Jul 5, 2017
    和 ls 相似,感觉应该用 child ViewController,child ViewController 也能复用。
    LINAICAI
        10
    LINAICAI  
       Jul 5, 2017
    永远不要让视图去处理网络数据,你要做的是拿到数据后把数据扔给视图然后刷新视图
    GaoMjun
        11
    GaoMjun  
       Jul 5, 2017 via Android
    viewcontroller 几千行正常
    Durandcol
        12
    Durandcol  
       Jul 5, 2017
    1.在需要复用的前提下 再对之前的代码做分层
    2.不要执拗于 MVC MVVM 本质上只是放代码的地方, 只是方便程序员维护与理解 搞了一层抽象的东西.
    3.继承不要搞太多层.
    xiubin
        13
    xiubin  
    OP
       Jul 5, 2017
    @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  
       Jul 5, 2017
    category
    jesse_luo
        15
    jesse_luo  
       Jul 6, 2017
    1. 减少继承,增加组合
    2. 没人说 view delegate 一定要用 VC 处理吧
    3. View 不要自己处理业务逻辑
    googlebot
        16
    googlebot  
       Jul 6, 2017 via iPad
    继承是非常差的架构,代码非常难维护,代码分离太差,
    出了问题你都不知道在第几层出的问题,
    akring
        17
    akring  
       Jul 6, 2017 via iPhone
    @xiubin 摸爬滚打这么些年,2,3k 的真不算什么…见过 10k+的
    free9fw
        18
    free9fw  
       Jul 6, 2017
    swift extension+RxSwift
    JasperYanky
        19
    JasperYanky  
       Jul 6, 2017
    1.可以试试 ViewModel
    2.可以试试 Category
    ma125125t
        20
    ma125125t  
       Jul 6, 2017
    @akring 2,3k 在 iOS 算挺多的了
    cheng4741
        21
    cheng4741  
       Jul 6, 2017
    不到万不得已别用继承,楼上说过的 extension,viewmodel 都是很好的方案,还可以另外写一个类处理一些逻辑,然后组合到 vc 中,各种 delegate 可以交给这个类去处理
    holy_sin
        22
    holy_sin  
       Jul 6, 2017
    rx.fuckEverything, you need it
    blacklee
        23
    blacklee  
       Jul 6, 2017
    用 category 是一个很不错的解决方案,一个实例(左边是.m 文件的代码行数)

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