
这个只是一个按钮的点击逻辑,界面中存在 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 1 summer1991 OP 求解答! |
2 xiubin 2017-06-15 22:41:56 +08:00 “于是 vc 中充斥大量的 逻辑判断,网络调用,弹窗调用,界面跳转,界面刷新等。请问怎么优化呢?” 对于通常比较大的页面,我的做法是写 vm,但不能解决你的问题。对于这种情况,你页面中的网络调用和弹窗都是已经封装成层,可优化力度也不大;我对于 Action、代理比较多的控制器的做法是用继承来分层解决,比如,第一层抽出基础共性,第二层完成视图构建,第三层就只做各种请求、Action、代理等。 |
3 ichanne 2017-06-15 23:35:51 +08:00 如果一个页面被产品设计为有很多个按钮,开发并没有多大的发挥余地来减少赘余代码。 毕竟每个按钮的触发、Action、结果、通知都是不可避免的。 当然,如果一个控件在其他地方也使用或者控件本身就可以处理逻辑,那可以把控件封装为 self-manager 式的,避免把可以自己处理的逻辑暴露出来,同时也能一键使用。 |
4 summer1991 OP @ichanne 这样不是把 View 和 Model,网络 这些杂糅在一起吗? |
5 summer1991 OP @xiubin 你的方案并没有解决问题 :-( |
6 xiubin 2017-06-17 19:40:41 +08:00 via iPhone @summer1991 如果你觉得把很多事件放在控制器中是需要优化的,那么最好的方法就是像楼上所说,每个控件的事件自己来处理,在控件中去网络请求、弹窗、转场 |
7 summer1991 OP @ichanne 恩 我又参考了下 sunnyx 的博客,感觉这个方法可以试一试 http://blog.sunnyxx.com/2015/12/19/self-manager-pattern-in-ios/ |