Ios 什么时候可以通过将代码放入AppDelegate来减少代码重复?

Ios 什么时候可以通过将代码放入AppDelegate来减少代码重复?,ios,objective-c,uiviewcontroller,duplicates,appdelegate,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 andAc

我有一个非常小的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 is-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]delegate],以便:

  • 我可以指定“弱”并避免可能的保留周期

  • 我只把一个指针指向AppDelegate(为早熟优化万岁>在我看来,类别正是针对这种情况而设计的——尽管正如其他人在评论中指出的,还有其他选项——这就是我所做的

    要查看苹果的分类文档,请参阅。
    要在Xcode中添加类别,请参阅。

    通过创建.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
    

    然后只需导入UIViewController+InfoAlert.h,在其中使用新的postInfoAlertWithTitle方法

    UIViewController
    上创建一个类别,该类别将包含这些方法(初始方法,而不是AppDelegate方法).
    UICollectionViewController
    UITableViewController
    继承自
    UIViewController
    ,因此这应该没问题。避免像这样使用AppDelegate添加太多不相关的信息。实际上,您使用的是它是一个单件(可以自己制作)。您可以创建一个“TipHelper”类并使用实例(或共享实例)因为继承对你来说不是一个容易的选择,组合是另一个可用的策略。Larme-啊哈,我不知道类别!非常有趣,我想,只是一张票!Phillip-嗯,是的,这也是一个很好的建议:基本上用助手类替换AppDelegate的实例。我知道uld提到,我之前就想到了这一点,但后来决定不这么做,因为我最终为每个控制器实现了参数化的init方法,以保持解耦(而尝试与AppDelegate解耦是没有意义的)。考虑到更多本质上“重复的”使用新的init方法编写代码时,我认为使用AppDelegate更容易。这两种方法都可以,但我同意您的建议更简洁。正如您所说的
    BaseViewController
    类似地,您可以创建
    BaseCollectionViewController
    BaseTableViewController
    继承
    BaseViewController
    not
    UIViewController
    并使用这两种方法,就像您在UIViewController中使用的一样所有方法都将遵循,这是一种更干净的方法,而不是创建类别,因为它允许您定义属性,并且避免使用
    AppDelegate
    ,因为它不会破坏自身,所以您可能最终会消耗内存。