iOS: 请问大家下面 ASHTempViewController 中这段代码怎么优化? (代码逻辑容易膨胀,如果 controller 中有多个这样的逻辑,会导致复杂的 vc) - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
summer1991
V2EX    iOS

iOS: 请问大家下面 ASHTempViewController 中这段代码怎么优化? (代码逻辑容易膨胀,如果 controller 中有多个这样的逻辑,会导致复杂的 vc)

  •  
  •   summer1991 2017-06-15 15:35:54 +08:00 2483 次点击
    这是一个创建于 3089 天前的主题,其中的信息可能已经有所发展或是发生改变。

    这个只是一个按钮的点击逻辑,界面中存在 N 个按钮,与这个逻辑类似。于是 vc 中充斥大量的 逻辑判断,网络调用,弹窗调用,界面跳转,界面刷新等。请问怎么优化呢? (继之前的主题,可能之前没描述好 t/368557#reply11

    //版本 v2 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //macro.h #ifndef weakify #if __has_feature(objc_arc) #define weakify( x ) autoreleasepool{} __weak __typeof__(x) __weak_##x##__ = x; #else // #if __has_feature(objc_arc) #define weakify( x ) autoreleasepool{} __block __typeof__(x) __block_##x##__ = x; #endif // #if __has_feature(objc_arc) #endif // #ifndef weakify #ifndef normalize #if __has_feature(objc_arc) #define normalize( x ) try{} @finally{} __typeof__(x) x = __weak_##x##__; #else // #if __has_feature(objc_arc) #define normalize( x ) try{} @finally{} __typeof__(x) x = __block_##x##__; #endif // #if __has_feature(objc_arc) #endif // #ifndef @normalize ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //store/pref/ASHPrefStore.h @interface ASHPrefStore : NSObject + (BOOL)haveReadBroadcastTip; + (void)setHaveReadBroadcastTip; @end //store/pref/ASHPrefStore.m @implementation ASHPrefStore static NSString *const kHaveReadBroadcastTipKey = @"haveReadBroadcastTip"; + (BOOL)haveReadBroadcastTip { return [[NSUserDefaults standardUserDefaults] boolForKey:kHaveReadBroadcastTipKey]; } + (void)setHaveReadBroadcastTip { [[NSUserDefaults standardUserDefaults] setObject:@(YES) forKey:kHaveReadBroadcastTipKey]; } @end ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //network/ASHNetworkAPI.h @interface ASHNetworkAPI : NSObject + (void)sendBroadcastRequestWithMsg:(NSString *)msg successBlock:(void(^)(void))successBlock failureBlock:(void(^)(NSError *error))failureBlock; @end //network/ASHNetworkAPI.m @implementation ASHNetworkAPI + (void)sendBroadcastRequestWithMsg:(NSString *)msg successBlock:(void(^)(void))successBlock failureBlock:(void(^)(NSError *error))failureBlock { //send request dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ !successBlock ?: successBlock(); }); } @end ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //utils/ui/ASHAlertUtils.h @interface ASHAlertUtils : NSObject + (void)showAlertWithController:(UIViewController *)controller msg:(NSString *)msg callback:(void(^)(void))callback; + (void)showEditAlertWithController:(UIViewController *)controller title:(NSString *)title placeholder:(NSString *)placeholder callback:(void(^)(NSString *content))callback; @end //utils/ui/ASHAlertUtils.m @implementation ASHAlertUtils #pragma mark - utils + (void)showAlertWithController:(UIViewController *)controller msg:(NSString *)msg callback:(void(^)(void))callback { UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:msg preferredStyle:UIAlertControllerStyleAlert]; [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { !callback ?: callback(); }]]; [controller presentViewController:alert animated:YES completion:nil]; } + (void)showEditAlertWithController:(UIViewController *)controller title:(NSString *)title placeholder:(NSString *)placeholder callback:(void(^)(NSString *content))callback { UIAlertController *alertCOntroller= [UIAlertController alertControllerWithTitle:title message:nil preferredStyle:UIAlertControllerStyleAlert]; [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { textField.placeholder = placeholder; }]; [alertController addAction:[UIAlertAction actionWithTitle:@"发送" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { NSString *cOntent= [[alertController textFields][0] text]; !callback ?: callback(content); }]]; [alertController addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { NSLog(@"Canelled"); }]]; [controller presentViewController:alertController animated:YES completion:nil]; } @end ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //controller/ASHTempViewController.m @implementation ASHTempViewController #pragma mark - app logic - (void)sendBroadcastWithSuccessBlock:(void (^)(void))successBlock { @weakify(self) void (^showSendBroadcast) (void) = ^{ [ASHAlertUtils showEditAlertWithController:self title:@"发送广播'" placeholder:@"说点什么..." callback:^(NSString *content) { //可能增加的业务 : 这里再做一些长度限制检查 [ASHNetworkAPI sendBroadcastRequestWithMsg:content successBlock:^{ @normalize(self) //可能增加的业务 : 做一些数据更新 和 界面刷新 !successBlock ?: successBlock(); } failureBlock:^(NSError *error) { @normalize(self) !self ?: [ASHAlertUtils showAlertWithController:self msg:error.localizedDescription callback:nil]; }]; }]; }; if ([ASHPrefStore haveReadBroadcastTip]) { showSendBroadcast(); } else { NSString *title = @"1、发布广播,全服玩家都可以看到;\n2、禁止发布反动、政治、色情、辱骂、广告等不良言论,否则将会遭到删除、封号处理。"; [ASHAlertUtils showAlertWithController:self msg:title callback:^{ [ASHPrefStore setHaveReadBroadcastTip]; showSendBroadcast(); }]; } } @end 
    7 条回复    2017-06-19 14:39:48 +08:00
    summer1991
        1
    summer1991  
    OP
       2017-06-15 15:47:07 +08:00
    求解答!
    xiubin
        2
    xiubin  
       2017-06-15 22:41:56 +08:00
    “于是 vc 中充斥大量的 逻辑判断,网络调用,弹窗调用,界面跳转,界面刷新等。请问怎么优化呢?”

    对于通常比较大的页面,我的做法是写 vm,但不能解决你的问题。对于这种情况,你页面中的网络调用和弹窗都是已经封装成层,可优化力度也不大;我对于 Action、代理比较多的控制器的做法是用继承来分层解决,比如,第一层抽出基础共性,第二层完成视图构建,第三层就只做各种请求、Action、代理等。
    ichanne
        3
    ichanne  
       2017-06-15 23:35:51 +08:00
    如果一个页面被产品设计为有很多个按钮,开发并没有多大的发挥余地来减少赘余代码。
    毕竟每个按钮的触发、Action、结果、通知都是不可避免的。
    当然,如果一个控件在其他地方也使用或者控件本身就可以处理逻辑,那可以把控件封装为 self-manager 式的,避免把可以自己处理的逻辑暴露出来,同时也能一键使用。
    summer1991
        4
    summer1991  
    OP
       2017-06-17 16:37:57 +08:00
    @ichanne 这样不是把 View 和 Model,网络 这些杂糅在一起吗?
    summer1991
        5
    summer1991  
    OP
       2017-06-17 16:38:40 +08:00
    @xiubin 你的方案并没有解决问题 :-(
    xiubin
        6
    xiubin  
       2017-06-17 19:40:41 +08:00 via iPhone
    @summer1991 如果你觉得把很多事件放在控制器中是需要优化的,那么最好的方法就是像楼上所说,每个控件的事件自己来处理,在控件中去网络请求、弹窗、转场
    summer1991
        7
    summer1991  
    OP
       2017-06-19 14:39:48 +08:00
    @ichanne 恩 我又参考了下 sunnyx 的博客,感觉这个方法可以试一试 http://blog.sunnyxx.com/2015/12/19/self-manager-pattern-in-ios/
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1000 人在线   最高记录 6679/span>       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 18:33 PVG 02:33 LAX 10:33 JFK 13:33
    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