2014年1月29日水曜日

iOSシミュレーターのUITextView/UItextFiledの入力バグ

シミュレーター上でのUITextView/UITextFiledではMacのキーボードから日本語を含め入力できるが、たまに出来なくなることがある。

シミュレーターで
 ハードウエア〜デバイス
で機器を切り替えると治ったが、ようやくもっと根本的に原因がわかった。

Commandキーが入力状態でロックされている。
なので、入力できなくなった状態でAを押すとCommand-Aとみなされ、全選択になる。
治すには、Commandキーを押せばよい。

入力中にCommand+<-/->で画面回転させると、発生する。
それ以外にも、MissionControlでのキー操作でも発生するので、
MacOS側でCommandを使うキー操作をすると軒並みダメになるみたい。

私はシステム環境設定のキーボードではControlとCommandを入れ替えているが、
それが影響している可能性はある。
いずれにせよシミュレーターのバグである。

追記:
Commandキーを押しても治らないこともある様子。その場合はデバイス切り替えをするか、シミュレーターを再起動するしかないかもしれない。

2014年1月22日水曜日

Block構文の罠

先日、ブロック構文で引っかかったので覚え書き。

たとえば、 イカのようなブロック構文を引数に保つメソッドを実装したとする。

- (void)blockTest:(id)arg
                       onSuccess:(void(^)(void))successBlock
                       onFailure:(void(^)(NSInteger errCode, NSError* error))failureBlock

この処理の中で通信とか遅い処理を行う。成功すればonSuccessが実行され、失敗すればonFailureが実行される、と言う作りである。

この時、

-(void)method
{
    [〜 blockTest:@"arg"
        onSuccess:^(void) {
            // 成功時処理
        }
        onFailure:^(NSInteger errCode, NSError *error) {
            // エラー処理
        }
    ];
    // 素通り
}
   
という処理はどう走るか。

実は、まず素通りし、methodからも抜けてしまう。
しかるのち、blockTestが実際に終了した時に、その結果に応じてonSuccessまたはonFailureのいずれか「だけ」が走る。
その時には素通りの部分は実行されない。

すなわち、(見かけ上)一旦抜けたメソッド内に、後から、非同期にまた戻ってくるということになる。
これは通常のCのプログラムでは考えられない動作なので理解が難しい。
(一旦抜けた関数の、さらにその中の一部の処理だけに戻ってくるというのはありえない。)

このブロック文はデリゲートの代わりだからこういうことになる。
なまじブロックでメソッド内に記述するからややこしくなるわけである。

ブロックは便利な記述方法ではあるが、プログラムの動きで言えば、記述の流れと処理の流れが一致せずわかりにくくなるので、
注意が必要である。

2014年1月15日水曜日

iOS7のUITextViewのバグ(その2)

iOS7のUITextViewには前にも書いたとおり、非常にたくさんのバグが存在するが、
またバグを発見してしまった。これは表に出てこないのでちょっとわかりにくいバグ。

 (1)入力状態にある間中、メモリ利用量が増加し続ける
64バイトずつメモリが確保され続けている。
だいたいではあるが13KB/分くらいの増加量。
調べると、libdispatch.dylibが_dispatch_continueation_alloc_from_heapを発行し続けているらしいが、
詳細は不明。

終了すると一括開放されるのでリークとはならない。



(2)メモリリークもある模様
しかし、別のところでメモリリークがある。内部で呼び出されていると思われる、NSUndoManagerというものが、メモリを開放しないで終了している。
1回あたりは少量だが、メモリリークが検出されること自体余り良い気分ではない。

なにはともあれ、iOS7のUITextViewはバグが多すぎて困る。一から作り直したりするからこういうことになるのだ。 従来版も残しながら新版をリリースし、以降を推奨しながら、バグが枯れた頃に旧版を廃止するのが普通ではないかと思うのだが、アップルには世間の常識は通用しないからなぁ。


おまけ
(3)UIDatePickerを回し続けると急激にメモリ利用量が増加する
ただし、止めて一定時間立つと開放される様子。
メモリ残り容量が少ない時にUIDatePickerを 動かすとメモリ不足で落ちたりするかもしれない。