私のアプリケーションはタブバーアプリケーションで、タブごとに個別のViewControllerがあります。
最初のViewController(A)に、保存されているすべてのアプリケーションデータ(NSUserDefaultsは無視してください)を含むオブジェクトがあります。このオブジェクトには、2番目のView Controller(B)のボタンを押したときにアクセスする必要があります。どうすればこれを最善の方法で達成できますか?
私のアプリケーションはタブバーアプリケーションで、タブごとに個別のViewControllerがあります。
最初のViewController(A)に、保存されているすべてのアプリケーションデータ(NSUserDefaultsは無視してください)を含むオブジェクトがあります。このオブジェクトには、2番目のView Controller(B)のボタンを押したときにアクセスする必要があります。どうすればこれを最善の方法で達成できますか?
あるオプションは、日付モデルをアプリデリゲートのインスタンス変数として宣言することです(他のコメント投稿者が言及しているように)。
nevanによって提案されたようにアプリデリゲートを参照する代わりに、データモデルのビューコントローラークラス(AおよびB)にプロパティを追加することもできます。
ビューコントローラ間でデータモデルオブジェクトを共有したいとします。それぞれにプロパティを追加できます。
@interface AViewController : UIViewController {
MyDataModel *model;
}
@property (nonatomic, retain) MyDataModel *model;
@end
@interface BViewController : UIViewController {
MyDataModel *model;
}
@property (nonatomic, retain) MyDataModel *model;
@end
ビューコントローラを初期化するときに、このプロパティを以前に初期化されたオブジェクトコンテキストに設定できます。
あなたはタブバーコントローラーについて言及しました。applicationDidFinishLaunching:
ビューコントローラがIBを介して配線されている場合は、タブバーコントローラが表示される前に、アプリケーションデリゲートメソッドでこれらのパラメータを設定するだけです。
@interface MyAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate>
{
MyDataModel *model;
AViewController *aViewController;
BViewController *bViewController;
...
}
@property (retain) IBOutlet AViewController *aViewController;
@property (retain) IBOutlet BViewController *aViewController;
@end
@implementation MyAppDelegate
...
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
...
aViewController.model = model;
bViewController.model = model;
[window addSubview:tabBarController.view];
[window makeKeyAndVisible];
}
dealloc
ビューコントローラのメソッドでモデルをリリースすることを忘れないでください。
別の方法は、シングルトンオブジェクトを使用することです。単純なシングルトンの例:
@interface MyDataModel : NSObject
{
}
+ (MyDataModel *) sharedDataModel;
@end
@implementation MyDataModel
static MyDataModel *sharedDataModel = nil;
+ (MyDataModel *) sharedDataModel
{
@synchronized(self)
{
if (sharedDataModel == nil)
{
sharedDataModel = [[MyDataModel alloc] init];
}
}
return sharedDataModel;
}
@end
次のようなものを使用して、すべてのViewControllerからこのデータモデルにアクセスできます。
MyDataModel *model = [MyDataModel sharedDataModel];
シングルトンに関するこのスタックオーバーフローの説明も参照してください。
私が見た最も一般的な方法は、アプリのデリゲートでアクセスしたいものを設定し、次のように他の場所で参照することです。
MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
myStuff = appDelegate.stuff;
app デリゲートで、stuff 変数を設定し、通常どおり @property と @synthesize を使用します。
グローバル変数を使用するのと同じなので、良いアプローチではないと言う人もいますが、非常に一般的です。
シングルトンであり、必要なすべての要素を含む最上位の Model クラスを作成するのが好きです。
また、Apple の例で一般的なハイドレート/デハイドレート パターンを使用して、オブジェクトに db キーだけを設定するトップ レベルのロード メソッドを与えることも役立ちます。
アプリ デリゲートでの一般的な使用方法は、次のとおりです。
[[MyModel sharedModel] load];
そして、View Controller で:
NSArray *myThing1s = [[MyModel sharedModel] thing1s];
NSArray *myThing2s = [[MyModel sharedModel] thing2s];
次に、thing1 と thing2 を反復処理し、詳細が必要な場合は呼び出すだけです。
[myThing1 hydrate];
これにより、オブジェクトが設定されます。
もちろん、CoreData を使用して 3.0 以降の永続性を管理することをお勧めします。
私はいつもと呼ばれる特別なオブジェクトを作成し、DataModel
それを使用します singleton sharedInstance
。
そして、このオブジェクトはすべてのアプリ関連データを保持します。恐ろしい にアクセスする必要はありませんappDelegate
。
DataModel.h
#import <Foundation/Foundation.h>
@class MyClass1, MyClass2;
@interface DataModel : NSObject
@property (copy, nonatomic) NSString *aString;
@property (assign) BOOL aBool;
@property (strong) MyClass1 *myObject1;
@property (strong) MyClass2 *myObject2;
+ (DataModel *)sharedModel;
@end
DataModel.m
#import "DataModel.h"
#import "Class1.h"
#import "Class2.h"
@implementation DataModel
- (id) init
{
self = [super init];
if (self)
{
_myObject1 = [[MyClass1 alloc] init];
_myObject2 = [[MyClass2 alloc] init];
aBool = NO;
aString = nil;
}
return self;
}
+ (DataModel *)sharedModel
{
static DataModel *_sharedModel = nil;
static dispatch_once_t onceSecurePredicate;
dispatch_once(&onceSecurePredicate,^
{
_sharedModel = [[self alloc] init];
});
return _sharedModel;
}
@end
そして(私は怠け者なので)入れDataModel.h
ましたapplication-prefix.pch
。
そうすれば、呼び出すだけでアプリケーションのどこからでも自分のデータにアクセスできます
[DataModel sharedModel]
両方のViewControllerは、3番目のオブジェクト(C)をdataSourceとして参照する必要があります。保存されているすべてのアプリケーションデータを含むこのオブジェクト(C)。
この場合、CはMVCのMになります。
各ViewControllerに次の宣言を追加します。
// SomeViewController.h
// Before @interface
@class MyDataSource;
// In the interface
IBOutlet MyDataSource *datasource;
@property(retain) IBOutlet MyDataSource *datasource;