什么时候通过将代码放在AppDelegate中来减少代码重复是可以接受的?

时间:2017-05-03 16:31:27

标签: ios objective-c uiviewcontroller duplicates appdelegate

我有一个非常小的Xcode项目,有几个视图控制器。我发现自己在其中复制了以下方法:

- (void)postTip:(NSString *)message {
    [self postInfoAlertWithTitle:@"Tip" andMessage:message andAction:@"Got it!"];
}

- (void)postInfoAlertWithTitle:(NSString *)title andMessage:(NSString *)message andAction:(NSString *)action {
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
    [alert addAction:[UIAlertAction actionWithTitle:action style:UIAlertActionStyleDefault handler:nil]];
    [self presentViewController:alert animated:YES completion:nil];
}

当然,这让我想到了如何删除(或至少减少)重复的代码。

显而易见的答案是将所需行为放在父类中,然后让我的视图控制器继承该类。但是,有些视图控制器的类型为UICollectionViewController,有些类型为UITableViewController,我不知道如何保留它们的集合和表格风格,如果我让它们从假设的MyViewController继承而来的话。 -a UIViewController。

所以我做了一些研究并看了一下协议。最初,这似乎是一个很好的选择,除了你不能为协议中声明的方法提供默认实现,这基本上是我想要的。

最后,我非常犹豫和自我厌恶,我考虑将行为放在我的AppDelegate类中,并附加一个参数以便于显示警报:

- (void)postTip:(NSString *)message toController:(UIViewController *)controller;
- (void)postInfoAlertWithTitle:(NSString *)title andMessage:(NSString *)message andAction:(NSString *)action toController:(UIViewController *)controller;

给定视图控制器中的调用如下所示:

[self.appDelegate postTip:@"Git gud!" toController:self];

瞧瞧!我想要的行为,我想要的地方,以及我必须做的所有事情都得到了AppDelegate的一个实例!但是......这对我来说并不合适。好像......很臭。此外,还有一些重复,即声明和初始化私有appDelegate属性,我已经注意这样做,而不是在需要的地方调用(AppDelegate *)[[UIApplication sharedApplication]委托],以便:

  • 我可以指定"弱"并避免可能的保留周期
  • 我只拿一个指向AppDelegate的指针(过早优化的欢呼>。<)

使用AppDelegate作为应用程序范围行为(如实用程序方法)的存储库是否被认为是可接受的,如果是这样,我是否对实现方式不必要的偏执:使用属性? (如果没有,我的选择是什么?)

2 个答案:

答案 0 :(得分:1)

通过创建.h和.m文件

绝对使用类别

的UIViewController + InfoAlert.h

@interface UIViewController (InfoAlert)

- (void)postInfoAlertWithTitle:(NSString *)title andMessage:(NSString *)message andAction:(NSString *)action;

@end

的UIViewController + InfoAlert.m

#import "UIViewController+InfoAlert.h"

@implementation UIViewController (InfoAlert)

- (void)postInfoAlertWithTitle:(NSString *)title andMessage:(NSString *)message andAction:(NSString *)action {
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
    [alert addAction:[UIAlertAction actionWithTitle:action style:UIAlertActionStyleDefault handler:nil]];
    [self presentViewController:alert animated:YES completion:nil];
}

@end

然后只需导入你想要使用新的postInfoAlertWithTitle方法的UIViewController + InfoAlert.h

答案 1 :(得分:0)

在我看来,类别的确是针对这种情况 - 尽管其他人在评论中指出,还有其他选择 - 这就是我所做的。

要查看Apple的类别文档,请参阅this page。 要在Xcode中添加类别,请参阅this page