1. ホーム
  2. iphone

[解決済み] ARCをやるかやらないか?そのメリットとデメリットを教えてください。[クローズド]

2022-10-21 16:07:02

質問

現在取り組んでいるプロジェクトのコードの大半はiOS 5.0より前に書かれたものなので、ARCはまだ使っていません。

私はちょうど疑問に思っていたのですが、手動で保持/解放しない利便性 (そしておそらく結果としてより信頼性の高いコード?) は、ARC を使用する「コスト」を上回りますか? また、ARC をお勧めしますか?

では。

  • ARCはプロジェクトにどれだけの利益をもたらすことができるのか?
  • ARCは、Javaのガベージコレクションのようにコストがかかるのでしょうか?
  • ARCを使用したことがありますか?使用したことがあれば、これまでのところどうでしたか?

どのように解決しましたか?

デメリットはありません。使ってください。今日それを行う。あなたの古いコードより速いです。あなたの古いコードより安全です。以前のコードより簡単です。ガベージコレクションではありません。GCの実行時オーバーヘッドがありません。コンパイラは、いずれにせよ、あなたがすべきすべての場所にretainとreleaseを挿入します。しかし、コンパイラはあなたよりも賢く、実際に必要とされないものを最適化することができます(ループのアンロール、一時変数の削除、インライン関数などができるのと同じです)。

さて、次に小さな欠点についてお話しします。

  • あなたが長年のObjC開発者なら、ARCコードを見たとき、1週間ほど痙攣するでしょう。これはすぐに克服できるでしょう。

  • Core Foundation コードへのブリッジングには、いくつかの (非常に) 小さな複雑さがあります。を処理する何かを扱う際に、より複雑な問題があります。 idvoid* . の C 配列のようなものです。 id のC配列のようなものは、正しく行うためにもう少し考える必要があるかもしれません。ObjCの派手な処理 va_args の派手な処理も問題を起こす可能性があります。ObjCポインタの計算を含むほとんどのことは、もっと厄介です。いずれにせよ、あまりないはずです。

  • を置くことはできません。 id の中に struct . これはかなりまれなことですが、データをパックするために使われることもあります。

  • 正しい KVC ネーミングに従わず、ARC と非 ARC のコードを混在させた場合、メモリの問題が発生します。ARC は、メモリ管理に関する決定を行うために KVC ネーミングを使用します。もし、すべてARCのコードであれば、両者で同じ"間違った"処理を行うので問題ありません。しかし、ARCと非ARCが混在している場合、ミスマッチが発生します。

  • ARCはObjC例外のスローの間にメモリをリークします。ObjC例外は、プログラムの終了に非常に近い時間であるべきです。もし、かなりの数のObjC例外をキャッチしているのであれば、使い方が間違っています。これは -fobjc-arc-exceptions を使用することで修正できますが、以下で説明するようなペナルティが発生します。

  • ARC は ObjC または ObjC++ コード内の C++ 例外スロー中にメモリをリークしませんが、これは時間と空間のパフォーマンスの両方を犠牲にしています。これは、ObjC++ の使用を最小限に抑える理由の長いリストの中のさらに別のものです。

  • ARC は、iPhoneOS 3 または Mac OS X 10.5 以前ではまったく動作しません。(このため、多くのプロジェクトで ARC を使用することができません)。

  • __weak ポインターは iOS 4 または Mac OS X 10.6 で正しく動作しません。これは残念ですが、かなり簡単に回避できます。 __weak ポインターは素晴らしいものですが、ARC のセールスポイントの 1 つではありません。

95%以上のコードでは、ARCは素晴らしく、それを避ける理由は全くありません(OSのバージョンの制限を処理できる場合)。非 ARC コードでは -fno-objc-arc をファイル単位で行うことができます。Xcodeは残念ながら、これを実際に行うのが必要以上に難しくしています。おそらく、非ARCコードを別のxcodeprojに移動して、これを簡略化する必要があります。

結論として、できる限り早く ARC に切り替え、決して後戻りしないようにしましょう。


EDIT

ARC を使用することは、Cocoa のメモリ管理ルールを知ることの代わりにはならない」という内容のコメントをいくつか目にしました。まず、すべてのコードで ARC を使用している場合、そのコードで 3 つのマジック ワード に違反しても、何の問題もありません。衝撃的な話ですが、そうなんです。ARCは、あなたが意図していないものを保持するかもしれませんが、それらも同様に解放するので、決して問題にはなりません。もし私が今日、Cocoaの新しいクラスを教えるなら、実際のメモリ管理ルールについては5分も使わないでしょうし、KVCネーミングについて説明するときにメモリ管理のネーミングルールについて触れる程度でしょう。ARC を使えば、メモリ管理のルールをまったく学ばなくても、実際にまともな初級プログラマになれると思います。

しかし、まともな中級プログラマにはなれません。Core Foundation と正しく連携するためにはルールを知る必要があり、すべての中級プログラマは CF をいつかは扱う必要があるのです。そして、ARC/MRC混在コードのルールも知っておく必要があります。そして、あなたが void* へのポインタ id へのポインタ (KVOを正しく実行するために引き続き必要) を提供します。そしてブロック...まあ、ブロック メモリ管理は奇妙なものです。

私が言いたいのは、基礎となるメモリ管理は依然として重要ですが、以前は新しいプログラマ向けにルールを説明したり言い直したりするのにかなりの時間を費やしていましたが、ARC ではそれがより高度なトピックになってきているということです。私はむしろ、新しい開発者にオブジェクトグラフの観点から考えてもらいたいと思っています。 objc_retain() .