2017-05-03 3 views
3

私はいくつかのビューコントローラを備えた非常に小さなXcodeプロジェクトを持っています。これは私が私が重複コードを削除する(または少なくとも軽減)かもしれない方法を考えました。もちろん、AppDelegateにコードを入れてコードの重複を減らすことは、いつ受け入れられますか?

- (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]; 
} 

:私は自分自身が彼らに次のメソッドを複製しました。

明らかな答えは、親クラスに目的の動作を入れてから、そのクラスからView Controllerを継承させることです。しかし、View Controllerの中には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]; 

Et voila!私が欲しい振る舞い、私が望むところでは、私はそれをやるだけでAppDelegateのインスタンスを手に入れます!しかし...それは私とうまく座りません。それは...臭いようです。さらに、いくつかの重複があります。つまり、プライベートのappDelegateプロパティを宣言して初期化していますが、私が必要なところで(AppDelegate *)[[UIApplication sharedApplication] delegate]を呼び出すのではなく、気をつけています。

  • 私は(>時期尚早の最適化のために万歳。<)「弱い」を指定し、私はAppDelegateに1つのポインタをのみ取る保持サイクル
  • 可能性を回避することができる

それはリポジトリとしてAppDelegateを使用するために許容できると考えられていますユーティリティメソッドのようなアプリケーション全体の振る舞いについては、もしそうなら、私は不必要です実装についての妄想の再:プロパティを使用して? (そうでない場合は、私の選択肢は何ですか?)

+4

「UIViewController」にカテゴリを作成します。このカテゴリには、メソッド(AppDelegateではなく初期のメソッド)があります。 'UICollectionViewController'と' UITableViewController'は 'UIViewController'から継承しています。だから大丈夫です。無関係な情報をあまりにも多く追加するようなAppDelegateの使用は避けてください。あなたが実際に使っているのは、それがシングルトン(自分で作ることができる)の事実です。 – Larme

+1

"TipHelper"クラスを作成し、さまざまなコントローラでそのインスタンスのインスタンス(または共有インスタンス)を使用できます。継承はあなたにとって簡単な選択肢ではないので、合成も利用可能な別の戦略です。 –

+0

Larme - ああ、私はカテゴリについて知りませんでした!非常に興味深い、と思います、ちょうどチケット! – kuipersn

答えて

0

カテゴリはまさにこのような状況を想定しているようですが、他の人がコメントに指摘しているように、追加オプションがあります。私はやった。

Appleのカテゴリのドキュメントを表示するには、this pageを参照してください。 Xcodeでカテゴリを追加するには、this pageを参照してください。

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 

その後、ちょうど+あなたのUIViewControllerをインポートInfoAlert。h新しいpostInfoAlertWithTitleメソッドを使用する場所

関連する問題