メンバへのアクセス方法

63 views
Skip to first unread message

Osamu

unread,
Aug 9, 2010, 1:45:32 AM8/9/10
to cocoa-dev-japan
iOS4.0 からマルチタスクがサポートされるようになりました。マルチタスクのサポートとして、xxxAppDelegate.m の

- (void)applicationDidFinishLaunching:(UIApplication *)application
- (void)applicationDidBecomeActive:(UIApplication *)application

を考えています。それぞれ、アプリ起動直後、バックグランドからの復帰直後です。

上記メソッド内から、「設定」で設定されるアプリケーション内のパラメータを読み出す class setPreference を定義しました。その
中のメソッド、setPrefs を使って読み出します。読み出したパラメータは class setPreference のメンバに格納されま
す。

 上記で設定された class setPreference のメンバを xxxViewController.m 内のメソッドから読み出したいの
ですが、うまくいきません。

 やりたい事をまとめると、setPrefs の呼び出しは xxxViewController 中からは行なわずに、
xxxAppDelegate 中から行いメンバは保持していている、と言う事です。static などのグローバルは使わない方法でなんとかならいも
のでしょうか?

よろしくお願いいたします。

wang

unread,
Aug 14, 2010, 3:36:36 AM8/14/10
to cocoa-dev-japan
Osamuさん

ちょっとやろうとしている内容が読み取りにくいです。まずsetXXXというのはかなりわかりにくい名前です。
小文字から始まっているのでメソッド名なのかクラス名なのか混乱しますし、setterメソッドなのかそうではないのかという機能的な混乱もありま
す。

命名規則は個々人の自由かもしれませんが、ある程度環境にあわせた方がほかの人間が読んで理解しやすくなるのでAppleの規約にあわせたほうがよいと
思います。クラス名は大文字始まり。アクセサメソッドでないならset/getからはじめないなど名前を変えたらどうでしょう。


それでやりたいことは
「設定」アプリケーションで設定する機能をもったアプリケーションが、マルチタスクで切り替えられたときにアプリ起動時や
復帰時にその「設定」アプリケーションで設定した値を読み出したいということでいいでしょうか?

設定項目がそれほど多くないのであればフラグ値程度でしょうから、使うたびに読み出しクラスを生成してもいいのではないかと
思います。がxxxAppDelegateクラスで保持したいのであれば、その設定を読み出す必要のあるクラスはxxxAppDelegateクラスへ

参照を持つのが早いと思います。

そうでなければ
(xxxAppDelegate *)[[UIApplication sharedApplication] delegate];
で取り出すことが可能です。

m_yukio

unread,
Aug 17, 2010, 9:44:47 AM8/17/10
to cocoa-dev-japan
村上です。
よく分からないのですが、要するに、アプリケーション全体の値を保持するクラスがあります。
それは、アプリケーションのコントローラである、デリゲート・クラスのメンバ変数です。
これをビュー・コントローラクラスからアクセスしたいのですが、グローバル変数にしてアクセスするのは、望ましくないので、上手い方法はないでしょう
か?ということでしょうか。

ちょうど、これに近いお話を先日のmosa entranceやiOS Developer勉強会.Urawaで発表させていただきました。

アプリケーション全体に関係する値を保持するクラスをアプリケーションのデリゲート・クラスのメンバ変数にします。
私は、このクラスをDocumentクラスとして、メンバ変数名をdocumentにしています。
そうしますと、wangさんの説明された方法でアクセスできます。

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

バックグラウンドからの復帰時には使えないと思いますが、これ以外にDocumentクラスとの関係を密にしない方法として、通知やKVOを使う方法も
あるかと思います。
私も、今、この方法も試しています。

m_yukio

unread,
Aug 17, 2010, 5:13:08 PM8/17/10
to cocoa-dev-japan
私の例、説明不足でした。
例では、Documentクラスをアプリケーションのデリゲート・クラスのメンバ変数(インスタンス変数)として保持し、それをプロパティにしていま
す。
誤解を受ける例でしたので、訂正させていただきます。

Osamu Ohashi

unread,
Aug 17, 2010, 8:35:56 PM8/17/10
to cocoa-d...@googlegroups.com
wang さん、

 アドバイスありがとうございます。もう一度、cocoa の coding convention を見直してみます。
 とりあえず、ご指摘通りにクラス名とメソッド名を変更してみました。

 クラス名
 AppPreference
 働き
 「設定」アプリで設定された当該アプリの項目のやり取りを管理するためのクラス

 メソッド名
 readPrefs
 働き
 「設定」アプリで設定された当該アプリの項目を読み取る

 AppPreference は xxxAppDelegate で初期化される。readPrefs は

- (void)applicationDidFinishLaunching:(UIApplication *)application
- (void)applicationDidBecomeActive:(UIApplication *)application

 のタイミングで呼ばれる。

 で、その後が wang さんからのアドバイスの私なりの理解なのですが、
 readPrefs 中に
 xxxAppDelegate* appDelegate = (jDialerAppDelegate*)[UIApplication
sharedApplication].delegate;
 を記述し、

 appDelegate.xxx = readPrefsで読み出した値;
 を設定して、

 xxxViewController から同様に、
 xxxAppDelegate* appDelegate = (jDialerAppDelegate*)[UIApplication
sharedApplication].delegate;
 を記述し、

 xxxViewControllerで設定した変数(メンバ)= appDelegate.メンバ

 を行い、xxxViewController で 「設定」で設定した値が使えるようになる。

と言うものです。

どうでせうか?

m_yukio さん、
 cocoa 勉強会の時に、色々と教えてください。


以上、よろしくお願いいたします。

2010年8月18日6:13 m_yukio <yukio.m...@gmail.com>:

> --
> このグループから退会するには、次へメールをお送りください。
> cocoa-dev-jap...@googlegroups.com
> その他のオプションについては以下にアクセスしてください。
> http://groups.google.com/group/cocoa-dev-japan
>

--
Osamu OHASHI
osamu....@gmail.com
http://www.teamknox.com
Google Wave - osamu....@googlewave.com
MS-messenger - ooo_...@hotmail.com
Skype - ooo_1115
twitter - teamknox
facebook - http://www.facebook.com/osamu.ohashi

Osamu Ohashi

unread,
Aug 17, 2010, 10:02:12 PM8/17/10
to cocoa-d...@googlegroups.com
下記、試してみましたが思ったような動作をしませんでした…。
うーん、手詰まりだな。

m_yukio

unread,
Aug 18, 2010, 6:13:46 AM8/18/10
to cocoa-dev-japan
村上です。
まず、私でしたらSetting.bundleの値を管理するクラスAppPreferenceをクラスxxxAppDelegateのインスタンス変
数にします。そして、読み取るタイミングになりましたら、クラスAppPreferenceの内容をアップデータ(readPrefs)させます。
もしかして、困っていらっしゃるのは、このアップデートとxxxViewControllerでの値の参照のタイミングが合わないという事なのでしょう
か?

例えば、通知を使って、クラスAppPreferenceの内容変更の通知をxxxViewControllerで受け取って、表示内容を更新した
り、

○AppPreference側
#define kDocumentDidCalculate @"DocumentDidCalculate"

NSNotificationCenter *center = nil;
center = [NSNotificationCenter defaultCenter];
[center postNotificationName:kDocumentDidCalculate object:self
userInfo:nil];

○xxxViewController側
NSNotificationCenter *center = nil;
center = [NSNotificationCenter defaultCenter];
[center addObserver:self selector:@selector(update:)
name:kDocumentDidCalculate object:nil];

- (void)update:(NSNotification *)notification
{
[self.tableView reloadData];
}

KVOで、参照している項目の更新を監視するというのは、どうでしょうか?

○xxxViewController側

[self.document addObserver:self
forKeyPath:@"perContributor"
options:(NSKeyValueObservingOptionOld |
NSKeyValueObservingOptionNew)
context:NULL];


- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
NSLog(@"self: %@", self);
NSLog(@"object=%@, keyPath=%@", object, keyPath);
NSLog(@"change=%@", change);
if ([keyPath compare:@"perContributor"]) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:3UL inSection:
0UL];
NSArray *indexPaths = [NSArray arrayWithObject:indexPath];
[self.tableView reloadRowsAtIndexPaths:indexPaths
withRowAnimation:NO];
}
}

Osamu Ohashi

unread,
Aug 19, 2010, 3:17:49 AM8/19/10
to cocoa-d...@googlegroups.com
m_yukio さん、

 コード例ありがとうございます。
 変更タイミングを通知する方法もありますね。そのタイミングで参照し直して、メンバを再設定する方法も確かにありですね。まだ、咀嚼しきれていないのでテストアプリを作ってみます。

 読み取りタイミングは xxxViewController
でその値を参照する時に読み取れればベストなんですけど、アプリが起動した後に適当なタイミングで読み取る (readPrefs の実行を行う)
と落ちてしまいます。awakeFromNib
の中(アプリが起動しきっていない)からなら、問題なく読み取れます。また、xxxAppDelegate の

- (void)applicationDidFinishLaunching:(UIApplication *)application
- (void)applicationDidBecomeActive:(UIApplication *)application

中からもアプリが起動しきっていないので、読み取れます。

要は読み取った値を保持していて、任意のタイミングで xxxViewController で参照出来ればいいんですが、こんなに難しくなると…。
それともこういう事は一般的では無いんですかね?

2010年8月18日19:13 m_yukio <yukio.m...@gmail.com>:

wang

unread,
Aug 20, 2010, 9:13:19 AM8/20/10
to cocoa-dev-japan
Osamu OHASHI さんのやり方でいいと思います。

うまく行かないのは別の問題だと思います。例えばクラッシュするというのは保持している値がintなどの値ではなオブジェクト値なのにretainして
いないなどの問題ではないでしょうか?

そのような視点でコードを見直してみるといいでしょう。


On 8月19日, 午後4:17, Osamu Ohashi <osamu.oha...@gmail.com> wrote:
> m_yukio さん、
>
>  コード例ありがとうございます。
>  変更タイミングを通知する方法もありますね。そのタイミングで参照し直して、メンバを再設定する方法も確かにありですね。まだ、咀嚼しきれていないのでテストアプリを作ってみます。
>
>  読み取りタイミングは xxxViewController
> でその値を参照する時に読み取れればベストなんですけど、アプリが起動した後に適当なタイミングで読み取る (readPrefs の実行を行う)
> と落ちてしまいます。awakeFromNib
> の中(アプリが起動しきっていない)からなら、問題なく読み取れます。また、xxxAppDelegate の
>
> - (void)applicationDidFinishLaunching:(UIApplication *)application
> - (void)applicationDidBecomeActive:(UIApplication *)application
>
> 中からもアプリが起動しきっていないので、読み取れます。
>
> 要は読み取った値を保持していて、任意のタイミングで xxxViewController で参照出来ればいいんですが、こんなに難しくなると…。
> それともこういう事は一般的では無いんですかね?
>
> 2010年8月18日19:13 m_yukio <yukio.murak...@gmail.com>:
> osamu.oha...@gmail.comhttp://www.teamknox.com
> Google Wave - osamu.oha...@googlewave.com
> MS-messenger - ooo_1...@hotmail.com
Reply all
Reply to author
Forward
0 new messages