[解決済み】ARCでブロックに自己の弱参照を必ず渡す?
質問
Objective-Cのブロックの使い方について、少し混乱しています。私は現在ARCを使用しており、私のアプリにはかなり多くのブロックがあり、現在常に以下を参照しています。
self
弱参照ではなく、弱参照です。このようなブロックの保持が原因なのでしょうか
self
で、deallocedされないようにするのですか?問題は、常に
weak
の参照
self
をブロックに入れるか?
-(void)handleNewerData:(NSArray *)arr
{
ProcessOperation *operation =
[[ProcessOperation alloc] initWithDataToProcess:arr
completion:^(NSMutableArray *rows) {
dispatch_async(dispatch_get_main_queue(), ^{
[self updateFeed:arr rows:rows];
});
}];
[dataProcessQueue addOperation:operation];
}
ProcessOperation.h
@interface ProcessOperation : NSOperation
{
NSMutableArray *dataArr;
NSMutableArray *rowHeightsArr;
void (^callback)(NSMutableArray *rows);
}
ProcessOperation.m
-(id)initWithDataToProcess:(NSArray *)data completion:(void (^)(NSMutableArray *rows))cb{
if(self =[super init]){
dataArr = [NSMutableArray arrayWithArray:data];
rowHeightsArr = [NSMutableArray new];
callback = cb;
}
return self;
}
- (void)main {
@autoreleasepool {
...
callback(rowHeightsArr);
}
}
解決方法は?
に注目しないことが有効です。
strong
または
weak
の部分は、ディスカッションの一部です。代わりに注目するのは
サイクル
の部分です。
A保持 サイクル は、オブジェクトAがオブジェクトBを保持するときに発生するループです。 と オブジェクトBはオブジェクトAを保持し、その状態でどちらかのオブジェクトが解放されると
- オブジェクトAは、オブジェクトBがその参照を保持しているため、解放されることはありません。
- しかし、Object B は、Object A がそれへの参照を持っている限り、決して解放されることはないでしょう。
- しかし、Object B がそれへの参照を保持しているため、Object A が解放されることはありません。
- アド・インフィニタム
このように、これら2つのオブジェクトは、すべてが正しく動作していれば割り当て解除されるはずなのに、プログラムの間ずっとメモリ上にぶら下がっていることになります。
つまり、私たちが心配しているのは、retainする サイクル ブロック自体にはサイクルを作り出すようなものはないのです。これは、例えば、問題ではありません。
[myArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop){
[self doSomethingWithObject:obj];
}];
ブロックが保持する
self
しかし
self
はブロックを保持しません。どちらか一方が解放されれば、サイクルは作られず、すべてがあるべきように割り当て解除されます。
どこで困るかというと、こんな感じです。
//In the interface:
@property (strong) void(^myBlock)(id obj, NSUInteger idx, BOOL *stop);
//In the implementation:
[self setMyBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[self doSomethingWithObj:obj];
}];
さて、あなたのオブジェクト(
self
) には、明示的な
strong
を参照する。そして、そのブロックには
暗黙の
への強い参照
self
. これはサイクルであり、今ではどちらのオブジェクトも適切に解放されません。
なぜなら、このような状況では
self
定義上
はすでに
strong
への参照を明示的に弱めることで解決するのが一番簡単です。
self
をブロックが使用できるようにします。
__weak MyObject *weakSelf = self;
[self setMyBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[weakSelf doSomethingWithObj:obj];
}];
しかし、これはあなたが従うべきデフォルトのパターンではありません。
を呼び出すブロックを扱う場合
self
! これは、そうでなければ self とブロックの間の保持サイクルを壊すためにのみ使用されるべきです。もしこのパターンをあらゆるところで採用すると、ブロックが
self
が解放されました。
//SUSPICIOUS EXAMPLE:
__weak MyObject *weakSelf = self;
[[SomeOtherObject alloc] initWithCompletion:^{
//By the time this gets called, "weakSelf" might be nil because it's not retained!
[weakSelf doSomething];
}];
関連
-
[解決済み] Int 型のインデックスを持つ [AnyObject]? の値を添え字として使用できません。
-
[解決済み] シミュレータへのサービス接続の開始に失敗しました Xcode
-
[解決済み] iPhoneが使用できません。デバイスを再接続してください
-
[解決済み] Info.plist ユーティリティのエラーです。"そのようなファイルがないため、Info.plistを開くことができませんでした"
-
[解決済み] このアクションは完了できませんでした。再試行 (-22421)
-
[解決済み] 起動画面にカスタムクラス名が設定されない場合がある
-
[解決済み] IBOutletsはARCのもとで強くなるべきか、弱くなるべきか?
-
[解決済み] Swiftではクロージャの内部では常に[unowned self]を使うべきか?
-
[解決済み】Objective-C ARC: strong vs retainとweak vs assign
-
[解決済み】weak referenceとunowned referenceの違いは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】印刷します。エントリ, ":CFBundleIdentifier", Does Not Exist
-
[解決済み】Cocoapodsをインストールできない - プロジェクト・ディレクトリにポッドファイルが見つからない
-
[解決済み] Int 型のインデックスを持つ [AnyObject]? の値を添え字として使用できません。
-
[解決済み] シミュレータへのサービス接続の開始に失敗しました Xcode
-
[解決済み] Info.plist ユーティリティのエラーです。"そのようなファイルがないため、Info.plistを開くことができませんでした"
-
[解決済み] SwiftUI vs Interface Builderとストーリーボード【非公開
-
[解決済み] Xcode Simulatorのアニメーションをエディタで再生すると、極端に遅くなる。
-
[解決済み] UILabelにスペース/パディングを追加する
-
[解決済み] アラート "デバッグを続けるには、開発者ツールへのアクセスが他のプロセスの制御を必要とします。これを許可するにはパスワードを入力してください。
-
[解決済み] UIViewAlertForUnsatisfiableConstraintsでトラップする方法は?