iPhone プログラムで UI 動作が不安定な場合の対処方法

SPECIAL


UI 動作が不安定でアプリがハングアップする場合

iPhone アプリを制作していた際に、UI 動作が妙に不安定で、時にハングアップする問題に悩まされたことがありました。

妙な不安定というのは、ビューを表示するのと併せて UILabel のテキストを更新したりすると、ラベルに表示されるテキストがなぜか逆さまに表示されることが時々あったり、ビューが表示された頃合いにアプリが強制終了してしまったりといった感じです。

 

こういった状況の場合、原因として考えられるのが、メインスレッド以外でビューを呼び出したり、UI に関する値を操作したときに発生することがあるようです。

もともと UI 操作はメインスレッド以外では推奨されていないようなので、NSOperation 等を利用してマルチスレッド化しているような場合には、UI 関連の処理はメインスレッドに委ねる必要があるようです。

別スレッドから UI の更新をかけなければいけない場合にも、例えば displayName という変数にリンクされた UILabel の表示文字列を変更したい場合には、次のようにして、メインスレッドでそれを実行するようにします。

[displayName performSelectorOnMainThread:@selector(setText:) withObject:@"TEXT" waitUntilDone:NO];

こうすることで、通常時の displayName.text = @"TEXT" に相当する処理を、メインスレッドで実行してくれるようになります。

別スレッドからの UI 操作の際には、このような配慮を徹底することで、冒頭で挙げたような妙な不安定さはすっかり解消されました。

 

他にも、例えばオブジェクトを非表示にしたいのに hidden プロパティーに YES を設定しても表示されたままということもありました。

こちらも、別スレッドで displayName.hidden = YES を設定していたのが原因でした。これについては、performSelectorOnMainThread で直接 setHidden を実行したくても withObject では BOOL を直接渡すことができないようなので、非表示にするためのメソッドをひとつ作ったうえで、それを performSelectorOnMainThread で呼び出すという形をとる感じになるようでした。