web-dev-qa-db-ja.com

ReactiveCocoa / libextobjcで弱体化と強化がどのように機能するかの説明

保持サイクルを回避するために@ weakify @ strongifyを使用する必要があることは理解していますが、実際にこれをどのように達成するかを完全には理解していませんか?

22
nacross

質問を書くとき、私はマクロの定義をもっとじっと見つめました、そしてあなたが推測するかもしれないようにそれはうまくいくと思います。

@weakifyは、渡したのと同じタイプの弱く参照される新しい変数を作成し、元の値を割り当てます。

@strongifyは、元の変数と一致する変数を作成しますが、ローカルスコープに存在し、@ weakifyによって作成された変数を割り当てます。

19
nacross

前処理前のコード:

@weakify(self)
[[self.searchText.rac_textSignal
  map:^id(NSString *text) {
      return [UIColor yellowColor];
  }]
 subscribeNext:^(UIColor *color) {
     @strongify(self)
     self.searchText.backgroundColor = color;
 }];

前処理後のコード:

@autoreleasepool {} __attribute__((objc_ownership(weak))) __typeof__(self) self_weak_ = (self);
    [[self.searchText.rac_textSignal
      map:^id(NSString *text) {
          return [UIColor yellowColor];
      }]
     subscribeNext:^(UIColor *color) {
         @try {} @finally {}
 __attribute__((objc_ownership(strong))) __typeof__(self) self = self_weak_; // 1
 self.searchText.backgroundColor = color;  //2
     }];

1:新しいローカル変数「self」を定義します。これはグローバルなものに影を落とします。

2:ここでは、ローカル変数「self」-self_weak_を使用しました。

チップ:

1.ブロックでself.xxxを使用した場合は、その上に@strongify(self)を配置する必要があります。

2. @weakify(self)を使用して変数self_weak_を定義することを忘れないでください。

(追記:私は英語を学ぼうとしています。私の言っていることが理解していただければ幸いです。)

27
dusty

何よりもまず、使用している@weakify@strongifyの実装は重要です。これらは、標準言語の一部ではないためです。 ReactiveCocoaバージョンを使用していると仮定すると、ここにニースがあります 記事 それらが何であるかとそれらがどのように機能するかについて。

ここにいくつかの関連する引用があります:

私たちが書いたコードnotでも、selfを安全に使用できます。 NSAssertマクロ。 selfを使用して、実際のivarを参照することも可能です。ただし、警告が発生するため、簡単に見つけられる間違いです。

さて、あなたは尋ねるかもしれません:もし私がstrongifyを使うのを忘れたらどうしますか?これはすばらしい部分です。weakifyは新しいローカル変数を作成するため、まったく使用されていない場合は警告が表示されます。

ご想像のとおり、weakifyの使用を忘れたが、その場所にstrongifyがある場合、コンパイラはエラーを表示します。

0
user3099609