【发布时间】:2017-10-01 14:35:50
【问题描述】:
我有一个非常小的 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-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] delegate] 以便:
- 我可以指定“弱”并避免可能的保留周期
- 我只使用一个指向 AppDelegate 的指针(为过早的优化欢呼>.
将 AppDelegate 用作应用程序范围行为(例如实用程序方法)的存储库是否被认为是可以接受的,如果是这样,我是否对实现 re: 使用属性感到不必要的偏执? (如果没有,我有什么选择?)
【问题讨论】:
-
在
UIViewController上创建一个类别,该类别将具有方法(初始方法,而不是 AppDelegate 方法)。UICollectionViewController和UITableViewController继承自UIViewController,所以应该没问题。避免像这样使用您的 AppDelegate 添加太多不相关的信息。您在现实中使用的是事实是它是一个单例(可以自己制作)。 -
您可以创建一个“TipHelper”类并在您的各种控制器中使用该类的实例(或共享实例)。由于继承对您来说不是一个简单的选择,因此组合是另一种可用的策略。
-
Larme - 啊,我不知道类别!非常有趣,而且,我认为,只是门票!
-
Phillip - 嗯,是的,这也是一个很好的建议:基本上用辅助类替换 AppDelegate 的实例。我应该提到我之前已经想到了这一点,但决定反对它,因为我最终为每个控制器实现了参数化的 init 方法,以保持事物解耦(而尝试与 AppDelegate 解耦是没有意义的)。鉴于使用新的 init 方法有更多的本质上“重复”的代码,我认为使用 AppDelegate 更容易。可以用任何一种方式提出论点,但我同意您的建议更简洁。
-
正如你所说,你有
BaseViewController同样你可以创建BaseCollectionViewController和BaseTableViewController继承BaseViewController而不是UIViewController并像使用 UIViewController 一样使用两者,所有方法都将遵循,这个更简洁的方法是创建类别而不是创建类别,因为它也允许您定义属性,并避免使用AppDelegate,因为它不会自我破坏,因此您最终可能会吃掉内存。
标签: ios objective-c uiviewcontroller duplicates appdelegate