typeof
を使用して、保持サイクルを回避するためにブロックで使用するself
への弱い参照を作成する方法を見つけようとしています。
私がこれについて最初に読んだとき、慣習は__block typeof(self) bself = self;
を使用することでしたが、それはコンパイルしますが、保持サイクルを避けるために___block
_を使用することはもはや機能せず、代わりに___weak
_を使用する必要があります。
ただし、__weak typeof(self) bself = self;
はエラーになります。
タイプ 'typeof(self)'(別名 'TUAccountsViewController * const __strong')にはすでに保持属性が設定されています
typeof
または別の呼び出しを使用して一般的にself
への弱い参照を作成する方法はありますか?
これは動作します!
__typeof__(o) __weak
BBlockプロジェクトでBBlockWeakSelf
として定義したものは、次のように使用できます。
BBlockWeakSelf wself = self;
https://github.com/kgn/BBlock/blob/master/BBlock.h
Aleph7の応答に基づいて編集されました。
最新のclangバージョンApple clangバージョン4.0(tags/Apple/clang-421.1.48)(LLVM 3.1svnに基づく)、つまりXcode 4.4 +、__typeof__((__typeof__(self))self)
トリックはもう必要ありません。 __weak typeof(self) bself = self;
行は問題なくコンパイルされます。
これを行う正しい方法は
__weak ActualClassName* weakSelf = self;
マクロは、コードに移植性のないメタ言語を追加することに加えて、変数が実際に何であり、実際にそれで何をしているのかを不明確にするだけです。
ActualClassNameが提供するよりも汎用的なクラスのバージョンが必要な場合は、self
が定義されているため、self
のクラスも定義されているため、self
を処理しません。定義済み。
そのような場合、継承ツリーで最も近いベースクラス名を使用する必要があります。NSObject
以上、決してid
を使用しないでください。
__weak MyBaseClassName* weakObject = object;
私の経験では、行く方法は以下を使用することです:
__typeof__(self) __weak weakSelf = self;
所有権修飾子が実際の変数の前にどのように属するかに注意してください。
それが使用されると何が起こるかは非常に明白であり、Xcodeで便利なコードスニペットにでき、これが必要なプロジェクトまたはクラスでさらに使いやすくなります。 (スニペットの補完ショートカットとして「ws」を使用します)
うーん..ここに弱い参照が必要です。
_ws{return}
_
できたこのために将来のプロジェクトにヘッダーを含める必要はなく、スニペットを使用するだけです。
タイトル:_Generic Weak Self Reference
_
プラットフォーム:All
言語:_Objective-C
_
完了ショートカット:ws
完了スコープ:_Function or Method
_
コード:__typeof__(self) __weak weakSelf = self;
Edit: comments およびXcode Snippet Infoに基づく所有者修飾子の位置に関するメモを追加
私はこれを使用して大丈夫だと思う:
__weak __typeof(&* self)weakSelf = self;
aFNetworkingのAFURLConnectionOperation.mコードを参照します。
なぜ使用しないのですか
__weak id bself = self;
C言語の方言をチェックしてみましたか?
Project Navigator-> Project-> Target-> Build Settingsに移動します
C言語の方言を探します。 c11からGNU99に変更します。
私はそれが役立つことを願っています:)
このマクロがあります
#define weaken(object) __typeof__(self) __weak weakSelf = object
そして、私はこのように使用します
weaken(self);
//The block referencing weakSelf goes here
declareBlockSafe(self)その後、ブロック内でblk(self)。 Selfは、任意の変数またはインスタンス変数です。プロパティとメソッドの戻り値にはdeclareBlockSafeAsを使用します。
Mike Ashの素晴らしいMAZeroingWeakRefをインポートすると、ARC以外でも動作します。 https://github.com/mikeash/MAZeroingWeakRef
#if __has_feature(objc_arc)
#define declareBlockSafe(__obj__) __weak typeof(__obj__) __tmpblk##__obj__ = __obj__
#define blockSafe(__obj__) __tmpblk##__obj__
#define blk(__obj__) blockSafe(__obj__)
#define declareBlockSafeAs(__obj__, __name__) \
__weak typeof((__obj__)) __tmpblk##__name__ = (__obj__)
#else
#define declareBlockSafe(__obj__) MAZeroingWeakRef *__tmpblk##__obj__ = [MAZeroingWeakRef refWithTarget:__obj__]
#define blockSafe(__obj__) ((typeof(__obj__))__tmpblk##__obj__##.target)
#define blk(__obj__) blockSafe(__obj__)
#define declareBlockSafeAs(__obj__, __name__) \
MAZeroingWeakRef *__tmpblk##__name__ = (__obj__)
#endif
</ code>
ARCにはblk()は本当に必要ありません。マクロを非ARCでも同じように使用できるようにするためです。
__unsafe_unretainedはどうですか?それは__weakほど安全ではありませんが、私が考えることができるのはそれだけです。また、なぜtypeof()を使用するのですか?