7

AppDelegateを使用してiOSアプリケーションのオブジェクト間でデータを共有する方法を説明するソースをいくつか見つけました。私はそれを非常に苦痛なく実装しました、そしてそれは私の状況では良いアプローチのように見えます。AppDelegateを使って何できるかを考えて、どこに線を引くべきか疑問に思います。

明らかに、 View Controller間でデータを共有したり、 Singletonオブジェクトを使用したり、NSUserDefaultsを使用したりする方法は他にもあります。AppDelegateを使用してデータを共有するのはいつ適切ですか?私の現在の状況では、このアプローチを使用して、プッシュ通知に使用されるappleDeviceTokenを保存しています。ユーザーがアプリにログインまたはログアウトするときに、そのトークンを使用します。


MyAppDelegate.hで、プロパティを宣言します。

@property (nonatomic, retain) NSString *appleDeviceToken;

MyAppDelegate.mで、appleDeviceTokenを合成してから、次のように設定します。

@synthesize appleDeviceToken;    

------------------------------------------------------

- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
  NSString *devToken = [[[[deviceToken description]
                          stringByReplacingOccurrencesOfString:@"<"withString:@""]
                         stringByReplacingOccurrencesOfString:@">" withString:@""]
                        stringByReplacingOccurrencesOfString: @" " withString: @""];
  appleDeviceToken = devToken;
}

次に、LoginViewController.mでそれを取得し、サーバーに投稿します。

  NSString *urlForDeviceTokenPost = [NSString stringWithFormat: @"/api/users/%i/appleDeviceToken", userId];

  MyAppDelegate *appDelegate = (MyAppDelegate*) [UIApplication sharedApplication].delegate;
  NSString *appleDeviceTokenStr = appDelegate.appleDeviceToken;

  AppleDeviceToken *appleDeviceToken = [[AppleDeviceToken alloc] init];
  appleDeviceToken.deviceToken = appleDeviceTokenStr;

  [[RKObjectManager sharedManager] postObject:appleDeviceToken delegate:self];

これはこれまでのところうまく機能していますが、これは理想的なアプローチですか?他に何を知っておくべきですか?

4

4 に答える 4

7

データとオブジェクトが本当にグローバルであるか、グラフのさらに下にプッシュできない場合。通常、この高レベルのストレージは必要ありません。同様に、実装には通常、アプリデリゲートに関する知識がほとんどまたはまったくないはずです-シングルトンよりも悪いことは何ですか?神-シングルトン:)アプリのデリゲートが複雑な場合は、問題が発生しています。アプリデリゲートのインターフェースが(を介して#import)多くの実装に表示されている場合、またはそれらが直接メッセージを送信している場合は、何かが間違っています。

(慣用的なObjC)シングルトンは必要ありません。アプリデリゲートのインスタンスが1つあります。

NSUserDefaultsは、(名前が示すように)小さな値を永続化するためのものです。共有する機能は副作用です。

この場合、データはUIKitによってアプリデリゲートにすでに送信されているため、データまたはのオブジェクト表現を保存するのに適した場所である可能性がありますこれらのメッセージを適切なハンドラーに転送することも検討してください。重要なポイント-ほとんどの場合、初期化をオブジェクトグラフに流し、可能な限り低いポイントから流します(たとえば、多くのオブジェクトがアプリデリゲートを参照するのとは対照的です)。そのため、アプリデリゲートがトップレベルのビューコントローラーのモデルを設定しているのが見えるかもしれませんが、ビューコントローラーはプッシュするビューコントローラーのモデルを設定できます。このようにして、依存関係を減らし、フローを制御し、原因と結果を追跡しやすくし、大規模なグローバル状態のコンテキストから解放されて、より簡単にテストできるようになります。

于 2012-08-20T23:35:04.417 に答える
5

次の行は、常に何か間違ったことをしたことを示しています。

MyAppDelegate *appDelegate = (MyAppDelegate*) [UIApplication sharedApplication].delegate;

アプリケーションデリゲートは、のデリゲートですUIApplication。それは理由でそれと呼ばれています。それは、またはとは呼ばれていませApplicationDataStoreApplicationCoordinator。あなたがアプリケーションにそれを要求し、delegateそれを他のものとして扱っているという事実は、あなたがid<UIApplicationDelegate>それがすることを任されていない何かをするようにそれを要求したことを意味します。それは物事のニーズを管理することを任務としていUIApplicationます(これは「「アプリ」が必要とするすべてのもの」を意味するわけではありません)。

この情報を保存する場所をすでに構築しているようですRKObjectManager。アプリデリゲートにトークンを渡してもらい、ログインビューコントローラーにそれをプッシュする時間であることに注意してもらいます。私は文字列@"/api/users/%i/appleDeviceToken"をViewControllerに入れませんでした。これは、ビューの表示とは関係ありません。これは、ネットワークスタック(に格納されているようです)にとっては何かですRKObjectManager。「ViewController」は、「ビューが表す操作のプロセッサ」ではなく、「ビューの表示を支援するためのコントローラ」を意味します。

于 2012-08-21T03:18:05.723 に答える
1

それは適切な使用法のようです。アプリケーションデリゲートは、すべてのアプリにすでに存在する簡単にアクセスできるオブジェクトであるため、誤用したくなります。ただし、実際の目的は、そのタイトルが示すように、テーブルビューデリゲートがテーブルビューオブジェクトに対して行うのと同じように、アプリケーションオブジェクトに対して決定を行うことです。

この場合、アプリケーション自体からデリゲートに渡された情報を保存しています。そこに線が引かれていると思います。

このトークンの保存は、リモート通知の処理に重点を置いた別のコントローラーオブジェクトがない限り、アプリデリゲートの目的に従っているようです。その場合、おそらくトークンをそのコントローラーに直接渡すだけです。

于 2012-08-20T22:32:49.790 に答える
0

私はもっ​​と実用的です。私のアプリのappDelegateは、tabBarControllerがどのように設定されているか、およびすべてのナビゲーションコントローラーを認識しているため、任意のクラスが他のクラスと通信できるようにするメソッドがいくつかあります。通常、これらはいくつかのクラスの単一インスタンスです(シングルトンではありません)。そうは言っても、そこに置きたいものがappDelegateに含まれるやむを得ない理由がない場合は、おそらくそこに属していません。

于 2012-08-21T01:30:59.367 に答える