2021年2月の投稿

アップデート 2

2回目のアップデートをリリースしました。
当初はスレッドまわりの見直しに取り掛かるつもりだったのですが、Ver.1.1のアップデートをリリースした直後にメモリーリークのバグが見付かってため、予定変更してバグ修正とトランジション追加のアップデートです。
バグが発覚したきっかけは、amazon prime videoで映画を観終わった後に、アプリの動作が重くなっていたので、状況を確認してみたら使用メモリが4GBにもなっていたことでした。盛大にメモリーリークが起きていたのです。検証してみたところ、他のアプリがフルスクリーン動作をしているときにメモリリークが起こることがわかりました。
これには二つの要素が絡みます。まず当アプリでは、他のアプリがフルスクリーン動作をしている時でも壁紙切替の進行を止めていないこと。システムの壁紙表示機能は、フルスクリーン動作のアプリがある場合には進行を止めています。背後で壁紙切替をしてもリソースの無駄にしかならないので本来はこれが正解だと思われますが、リソースの消費は微々たるものなので、それを無視すれば止めても止めなくてもどちらでも構わないというのが実情です。なので当初迷ったのですが、将来的に環境設定で選べるようにするとして、当面は続行させる仕様としたのです。止めても止めなくてもどちらでもいいのなら、手順の少ない方にしたわけです。これがまず第一点。
次に、当アプリで大容量のメモリリークを引き起こす要因は、表示の終わった画像のViewの削除漏れしかないのは、制作の段階からわかっていました。当アプリでは、現在表示中のViewと、次の画像を表示させるViewの二つしかViewを作らないので、表示切替が終わったら前の画像のViewを決め打ちで削除するコードを書いていました。一抹の不安はありましたが、コードの進行上三つ目のViewが作られることなどありえないはずと考えていましたが、そこに落とし穴があったようです。
なのでメモリリークを引き起こしている箇所はわかっていたので、コードの修正はすぐにできたのですが、どういう過程を経てViewの削除漏れが発生するのか、そのプロセスがわかりませんでした。
当アプリの表示切替の進行の流れは大雑把に次のようになっていました。


- (void)キュー実行メソッド {  ⬅️ タイミング 1
 表示切替メソッド呼び出し
 //次の表示の遅延実行
 [self performSelector:@selector(キュー実行メソッド) 
            withObject:添付オブジェクト 
            afterDelay:インターバル];
} //このメソッドを抜けた後に遷移エフェクトが始まる

- (result)表示切替メソッド: {
 現在表示中(前の)のView = ・・・確保
 次の画像を表させるView = 画像を読み込んで生成
 次の画像を表させるView を デスクトップに追加

 //遷移エフェクトの開始
 [CATransaction begin];
 [CATransaction setCompletionBlock:^{ ⬅️ タイミング 2
  //遷移エフェクトの後処理
  前のViewの削除
  }]:
 switch (トランジションのタイプ)
 {
  case タイプ1:
  {
   アニケーション設定
   [前もしくは次のView.layer addAnimation:設定したアニメーション];
   break;
  }
  case タイプ2:
    ・
    ・
 }
 [CATransaction commit];
}

キュー実行メソッドの中で、表示切替メソッドと次のキュー実行メソッドの予約を同時に行っていますので、切替間隔の時間の中に遷移エフェクトにかかる時間も含まれます。そのため、アプリ側の予約設定として最短の表示時間を5秒、遷移エフェクトの最長時間を4秒にしていました。
コードのあちらこちらを色々検証してみた結果、他のアプリがフルスクリーン動作中は、ポイントとなる二箇所の実行タイミングが、システムによってルーズに呼び出されているのが原因だとわかりました。
その様子を視覚的に示しているのが、XCodeがアプリの使用メモリの時間経過を表示したグラフです。



システムがなぜこのような計らいをするのかはとりあえず置いといて、結果遷移エフェクトが終わって後処理のブロックが呼び出される前に、次のキュー実行メソッドが呼び出される場合があるのが、ロジックが狂う原因でした。
呼び出しのタイミングが遅延するのはどうでもいいことですが、処理の順序が前後するのは困るので、Viewを確実に削除する修正だけでなく、次のキュー実行メソッドの予約を遷移エフェクトの終了通知の呼び出しの中で行うよう変更しました。これによって壁紙の表示時間の中に遷移エフェクトにかかる時間が含まれなくなり、最短の表示時間と遷移エフェクトの最長時間の絡みもなくなりました。遅延実行のメソッドも利便性を考慮してタイマーオブジェクトに変更し、結果進行を管理しているコードにかなり手を加えることとなりました。

今回の予定外のアップデートは、いい意味で怪我の功名でした。Ver.1.0のリリース時はシステムのスリープとモニタ構成の変化に対応させるのに手一杯で、フルスクリーン動作への対応を後回しにしたせいで、今回の事態に遭遇し、おかげでアプリの動作への理解が深まり、コードも練り込むことができました。又、バグ修正だけのアップデートではつまらないので、もう少し先のことになる予定だったCIFilterを使ったアニメーションにも挑戦しました。ver.1.1で実装したアニメーションはレイヤーのプロパティ変更によるものに留まっていましたが、やっぱり遷移エフェクトといったらCIFilterを使ったものが本命なので、それを前倒しで実装できたのは大きかったです。
時間ができたらCIFilterを使ったアニメーションについても記事にしたいと思います。

コメントする

※ 匿名希望の場合は空欄で構いません。


コメントを追加する キャンセル

猫の食事事情

体の大きさがほぼ一人前になり、成長期が終わりを迎えたのか、食欲が落ち着いてきたジジとチャチャですが、ちょっと前まで餌の時間はすごい騒ぎでした。餌の用意を始めるとジジは部屋中を走り回り、チャチャは近所迷惑なくらい鳴きまくり、トレイを置くと唸り声をあげてがっついていました。近所にいるたまに猫たちに餌をあげてくれる奥さんが、ある時うちの子たちも含めた数匹に取り囲まれて怖い思いをされたそうですが、YouTubeを見てるとどこの猫も成長期は同じ感じみたいで、人によっては恐さを感じるほどです。うちの場合、ジジは走り回るタイプなのでまだマシですが、チャチャがよく鳴く子でうるさくてしょうがなかったです。
そんな彼らが、先日餌を食べなくなったことがありました。

〜猫の拒食〜
猫はたまに吐き戻しをします。ネットで調べると毛玉が原因としか情報がなく理由がよくわかりません。先日チャチャが一日に二度吐いたことがありましたが、その日以来まる三日、一度だけ少し食べた以外は缶詰もカリカリも全く食べなかったことがありました。その後ジジも吐き戻し、ジジも餌を食べなくなりました。結局チャチャの食欲が戻るのに五日、ジジは二日かかりました。これ、たまたま私が見てる前で吐いたので事情を把握できてよかったです。人間の吐き戻しは心身ともにダメージが大きいものですが、猫の場合毛玉が理由で吐く分には、何事もなかったようにケロっとしていて元気なので、もし私が外出してる時に外で吐いてたら、元気はあるのに突然餌を食べなくなった事態に相当困惑していたと思います。猫はたまにこうなることがあるという経験になりましたが、あの食欲旺盛だった子たちが餌を食べない様はやはり心配になりました。缶詰もカリカリも食べないと正直お手上げです。チャチャは吐いてから三日間ほとんどキャットフードを食べず、四日目にイワシを一尾与えたら食べたのでほっとしましたが、再びキャットフードを食べるようになったのは六日目でした。総合栄養食は、それと水だけで生きていけるように作られていると銘打っていますが、やはり人の造った工業製品なので、栄養素の方ではなく非栄養素の方が気になります。どんな食べ物にも少なからず非栄養素があるので、同じものばかりをずっと食べ続けるのは良くないので、たまには違うものを食べさせたいのですが、生魚を与えても必ずしも食べるとは限らないのが難しいところです。生きた雀を丸ごと一羽食べるくらいなので、多分ピチピチ跳ねた生きた魚なら食べそうですが。

ちなみに私の知るだけでも、チャチャが2回、ジジが1回生きた雀を捕まえてきたことがありました。しばらく遊んだ後、頭まで全部キレイに食べてました。仔猫の時から思う存分取っ組み合いと追っ掛けっこをし、夏になる頃から毎日のように虫を捕まえてきては食べ、大きくなってついに雀を捕まえられるまでになりました。飼い主としては何気にそこが自慢だったりします。うちの子達はちゃんと狩りができる猫なのです。

コメントする

※ 匿名希望の場合は空欄で構いません。


コメントを追加する キャンセル

▼ 記事の選択 ▼

最近の投稿