イベント処理を含むAPIを作成していますが、ハンドラにブロックを使用できるようにしたいと考えています。コールバックは、しばしば自己にアクセスしたり変更したりしたいと考えます。 ARCモードでは、Clangはselfを参照するブロックが保持サイクルを作成する可能性があることを警告します。これは一般的に続行しておきたい有用な警告のようです。自己参照ブロックのアーク保持サイクル警告をコンパクトに無効にする
ただし、このAPIの部分では、コールバックとそのオブジェクトを含むライフサイクルのライフサイクルは外部的に維持されます。私は、オブジェクトの割り当てを解除する必要があるサイクルを中断することができることを知っています。
ファイルごとに#pragma clang diagnostic ignored "-Warc-retain-cycles"
で保持周期の警告をオフにすることはできますが、ファイル全体の警告は無効になります。私はその警告の周りに#pragma clang diagnostic push
とpop
のブロックを囲むことができますが、それはブロックを醜いものにします。
自分自身を直接参照するのではなく、selfを指す__weak変数を参照して警告を出すこともできますが、ブロックを使用するのがはるかに面白くありません。それは、ネストされたことはできません、
#define OBSERVE(OBJ, OBSERVEE, PATH, CODE) \
[(OBJ) observeObject:(OBSERVEE) forKeyPath:(PATH) withBlock:^(id obj, NSDictionary *change) { \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Warc-retain-cycles\"") \
do { CODE; } while(0); \
_Pragma("clang diagnostic pop") \
}];
動作しますが、それはAPIユーザーにとって非常に見つけていないのです。
私が作ってみた最善の解決策は、ブロックの周り診断無効化を行い、このマクロですXCodeのエディタとのやりとりが悪いです。警告を無効にするか回避するためのより良い方法はありますか?
#pragma clang diagnostic push
#pragma clang diagnostic ignored "<#A warning to ignore#>"
<#Code that issues a warning#>
#pragma clang diagnostic pop
しかし、それは問題が修正されませんので、私は、この特定のケースでそれを使用することはありません。そこに#pragma
を使用してコードの特定の行に対する警告を無効にする簡単な方法があり、そもそも
'self 'への' __weak'リファレンスを作成するには、文字通り1行のコードが必要です。私はこの場合の問題を解決することが症状を緩和しようとするよりも良いと思う。どのように 'self'の代わりに' weakSelf'を参照すると、ブロックの使い勝手が悪くなりますか? –
それはカップルの方法でそれほど快適ではありません。リスナーは、しばしば非常に短く、時には単一のステートメントです。 __weak宣言は、リスナーのサイズを2倍にします。また、推論された自己を使用するのではなく、プロパティのアクセスを修飾する必要があることを意味します。私の現在の解決策はおそらく__weakを使用するよりも悪いことに同意するでしょうが、私はこの質問を通してより良い解決策を得ることを望んでいました。 –
"self"引数を受け入れるように補完ブロックのプロトタイプを変更できますか?今度はブロックを渡すコードは同じように見えます(余分な引数を1つ受け入れることを除いて)、警告を取り除くことができます。 (すなわち、あなたのAPIが問題のオブジェクトをあなたのブロックに渡すようにしてください) – nielsbot