So-net無料ブログ作成
検索選択
-| 2010年09月 |2010年10月 ブログトップ

release して null を詰めるメソッド

release して null(nil) を詰めるメソッド

久しぶりにポインタとかを扱うとすっかりわすれていたのでメモ。

UIImageView(のポインタのポインタ)を受け取って、release して、removeFromSuperview
してnilを詰める。
- (void) releaseUIImageView:(UIImageView**) p_iv {
UIImageView* i = *p_iv;
[i removeFromSuperview];
[i release];
(*p_iv) = nil;
}

使い方は
UIIMageView* iv=[[UIImageView init] alloc];
[self addSubview:iv];
[self releaseUIImageView:&iv];

という感じでポインタのアドレスを渡す。

配列に入れたUIリソースの解放 [iphone]

配列に入れたUIリソースの解放
メンバ変数で
NSMutableArray* imgList;

というのを持って、画像というかUIImageViewから派生させた自作クラスの
ClickableImageViewというのを管理している。

で、ただ単に
[imgList release];

しても中のそれぞれの要素の release はしてくれないことに気がついた。

とりあえず次をやってみたらちゃんと解放された(deallocが呼ばれた)。もっと自動的にやってくれる方法はないだろうか。。。
while([imgList count] != 0) {
int idx = [imgList count]-1;
ClickableImageView* last = [imgList objectAtIndex:idx];
[last removeFromSuperview];
[last release];
[imgList removeObjectAtIndex:idx];
}
imgList release];
imgList = nil;

UIリソースの解放 [iphone]

cメンバ変数で
ClickableImageView* m_iv;
というUIImageViewの派生クラスのオブジェクトをもっているのだが、実はiphoneプログラミングでのUIリソースの解放がよくわかっていなかったのでメモ。

生成&画面に表示はViewControllerのなかで
m_iv = [[ClickableUIImageView alloc] init];
[self.view addSubview:m_iv];

解放は
[self.view removeFromSuperview];
[m_iv release];
しなければならない。

addSubviewでretainCountが+1され、removeFromSuperviewで-1され
るようだ。

NSLoc(@"retainCount=%i",[m_iv retaionCount]);
でretainCountを出力してみると addSubview 直後は2になっていて、
解放するときはなんと3になって勝手に1増えていた。しかし上記の解放
方法で(retainCountは1までしか戻らないが)deallocは呼ばれた。呼ばれた
ときのコールスタックをみるとAutoReleasePoolなるものから呼ばれていた。
自動的に管理されるのかよくわからないが、とにかく上記解放コードは実行しなければ、
画像を取り替えてm_ivを再利用するときにリークするので、忘れずに実行したい。

iPhoneSDKというかObjective-Cでコールバック [iphone]

ViewBのボタンを押すとViewAのメソッドを呼び出したいとき。

ViewAで呼ばれるメソッドを作る
// ViewA.h
- (void) backToMenuCallback:(BaseViewController*)sdr withValue:(NSNumber*);


// ViewA.m
- (void) backToMenuCallback:(BaseViewController*)sdr withValue:(NSNumber*) {
    // do something
}


ViewBにセレクタとViewAのインスタンスを保持しておく
//ViewB.h
@interface ViewB : UIViewController {
	SEL OnClick;
	NSObject* target;
}
//セッターも作っておく
- (void)setHandler:(SEL) method: (NSObject*) eventDest;


// ViewB.m 
- (void)setHandler:(SEL) method: (NSObject*) eventDest {
	OnClick = method;
	target = eventDest;
}


これらの変数にプロパティやセッターやらで設定しておく。
// ViewA.m
SEL s = @selector(backToMenuCallback:withValue:);
[viewcon setHandler:s :self];


ViewBのボタン押下のイベントハンドラでOnClickを呼び出す
// ViewB.m
[target performSelector:OnClick withObject:self withObject:[NSNumber numberWithInt:(int)TransitToSetting]];
selfと[NSNumber...]は引数で渡したいオブジェクトを入れる。


こうすれば、ViewBのボタンでViewAのメソッドが呼ばれる。
別にUIViewControllerの派生クラスでなくても何でもよいのですが、
一般的なのでそのまま残しておきます。

----

これで満足していたらなにやらイベントディスパッチャーを使ったイベント処理
があるそうではないですか!イベント処理の方が行儀が良いのでそのやり方を。

ViewAで呼ばれるイベントハンドラ定義
// ViewA.h
- (void) transitView:(NSNotification*)note;


ViewAのDidLoadとかでイベントリスナに登録
// ViewA.m
// "MyEvent"という名前のイベントが発行されたらtransitViewが呼ばれる
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(transitView:) name:@"MyEvent" object:nil];


ViewBからイベント発行
// ViewB.m
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
// イベントをポスト。argはイベントハンドラに渡す引数
[center postNotificationName:@"MyEvent" object:arg];


// ViewA.m
- (void) transitView:(NSNotification*)note {
        // argを取り出す
	id obj = [note object];
}


ディスパッチャーはcocoa touchのフレームワークだそうです。
こっちのほうがわかりやすいかな。引数が1こまでですが、
むしろなぞの引数がたくさんあるより、自前引数クラスで
管理したほうがわかりやすいので問題なしかな。
うーん、いろいろ知らないことたくさんあるなー。

タグ:iPhone

-|2010年09月 |2010年10月 ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。