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

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

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

    这个只是一个按钮的点击逻辑,界面中存在 N 个按钮,与这个逻辑类似。于是 vc 中充斥大量的 逻辑判断,网络调用,弹窗调用,界面跳转,界面刷新等。请问怎么优化呢? (继之前的主题,可能之前没描述好 https://www.v2ex.com/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   ·   实用小工具   ·   2644 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 04:04 · PVG 12:04 · LAX 20:04 · JFK 23:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.