iOS 开发中,把一个比较大的控制器(ViewController)通过继承来把视图布局和事件分开,这样好不好? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
xiubin
V2EX    程序员

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

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

    在项目中经常会碰见一个比较大点的 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。 就怕以后加业务逻辑会写太多多余代码。。
    yemoluo
        6
    yemoluo  
       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     Solana     1227 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 46ms UTC 23:37 PVG 07:37 LAX 16:37 JFK 19:37
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86